package com.tbit.uqbike.client.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tbit.common.constant.*;
import com.tbit.common.entity.*;
import com.tbit.uqbike.client.business.machine_op_log.service.MachineOpLogService;
import com.tbit.uqbike.client.business.user_op_log.service.UserOpLogService;
import com.tbit.uqbike.client.config.DelayPayQKBJSwitch;
import com.tbit.uqbike.client.constant.*;
import com.tbit.uqbike.client.constant.enums.PayApiTypeEnum;
import com.tbit.uqbike.client.dao.capital.BadOrderDao;
import com.tbit.uqbike.client.dao.capital.RideLogDetailsDao;
import com.tbit.uqbike.client.dao.core.DispatchLogDao;
import com.tbit.uqbike.client.dao.core.MachineBorrowDao;
import com.tbit.uqbike.client.dao.core.RechargePayTypeDao;
import com.tbit.uqbike.client.dao.core.UserToAgentDao;
import com.tbit.uqbike.client.dao.log.RechargeGiveLogDao;
import com.tbit.uqbike.client.dao.log.RefundOrderDao;
import com.tbit.uqbike.client.dao.log.UserMealLogDao;
import com.tbit.uqbike.client.dto.EventPutDTO;
import com.tbit.uqbike.client.exception.BaseException;
import com.tbit.uqbike.client.pojo.*;
import com.tbit.uqbike.client.pojo.newEntity.*;
import com.tbit.uqbike.client.pojo.vo.VipLogDot;
import com.tbit.uqbike.client.remote.WeixinPay;
import com.tbit.uqbike.client.remote.WxzffModelMsgUtil;
import com.tbit.uqbike.client.remote.tenxun.WxUtils;
import com.tbit.uqbike.client.service.*;
import com.tbit.uqbike.client.service.event.EventHandleService;
import com.tbit.uqbike.client.util.*;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

@Service("weixinPayService")
@Slf4j
public class WeixinPayServiceImpl implements WeixinPayService {
    @Autowired
    private RechargeService rechargeService;
    @Autowired
    private UserService userService;
    @Autowired
    private WeixinPayConfigService weixinPayConfigService;
    @Autowired
    private MemberFeeService memberFeeService;
    @Autowired
    private MemberLogService memberLogService;
    @Autowired
    private RideCardService rideCardService;
    @Autowired
    private RideCardUserService rideCardUserService;
    @Autowired
    private AdAccountDepositService adAccountDepositService;
    @Autowired
    private VipCardService vipCardService;
    @Autowired
    private VipCardLogService vipCardLogService;
    @Autowired
    private AgentDepositVipService agentDepositVipService;
    @Autowired
    private UserAccountLogService userAccountLogService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private RechargeGiveService rechargeGiveService;
    @Autowired
    private GiftCardUserService giftCardUserService;
    @Autowired
    private CouponService couponService;
    @Autowired
    private WeixinDepositLogService weixinDepositLogService;
    @Autowired
    private CouponUserService couponUserService;
    @Autowired
    private RideLogService rideLogService;
    @Autowired
    private MachineService machineService;
    @Autowired
    private RechargeGiveLogDao rechargeGiveLogDao;
    @Autowired
    private AccountBusBoundService accountBusBoundService;
    @Autowired
    private TerControlService terControlService;
    @Autowired
    private MachineBorrowDao machineBorrowDao;
    @Autowired
    private CouponMealService couponMealService;
    @Autowired
    private UserMealLogDao userMealLogDao;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private AdaPayService adaPayService;
    @Autowired
    private UserAdaPayMoneyService userAdaPayMoneyService;
    @Autowired
    private WeixinPushModelService weixinPushModelService;
    @Autowired
    private UserWxzffService userWxzffService;
    @Autowired
    private RidePayLogService ridePayLogService;
    @Autowired
    private AccountService accountService;
    @Autowired
    private PushMsgLogService pushMsgLogService;
    @Autowired
    private RideLogDetailsDao rideLogDetailsDao;
    @Autowired
    private UserToAgentDao userToAgentDao;
    @Autowired
    private UserAccountMoneyService userAccountMoneyService;

    @Autowired
    private AdaPayLogService adaPayLogService;
    @Autowired
    private UserAdaPayLogService userAdaPayLogService;
    @Autowired
    private RideUseLogService rideUseLogService;
    @Resource
    private BadOrderDao badOrderDao;
    @Autowired
    private RechargeMerchantService rechargeMerchantService;
    @Autowired
    private DispatchLogDao dispatchLogDao;
    @Autowired
    private UserOtherBoundService userOtherBoundService;
    @Autowired
    private CardAccountBoundService cardAccountBoundService;
    @Autowired
    private RefundOrderDao refundOrderDao;
    @Autowired
    private MQProducer mqProducer;
    @Resource
    private UserAdaPayLogTempService userAdaPayLogTempService;
    @Resource
    private DelayPayQKBJSwitch delayPayQKBJSwitch;
    @Autowired
    private RechargePayTypeDao rechargePayTypeDao;
    @Autowired
    private UserOpLogService userOpLogService;
    @Autowired
    private RefundOrderService refundOrderService;

    @Setter
    @Value("${payment.chargeReturnBikeGapSeconds:60}")
    private int chargeReturnBikeGapSeconds = 60;
    @Autowired
    private MachineOpLogService machineOpLogService;
    @Autowired
    private EventHandleService eventHandleService;

    public static Integer tranbusinessType(Integer type) {
        if (type.equals(RechargeConstant.RECHARGE_WEIXIN_APP) || type
                .equals(RechargeConstant.RECHARGE_WEIXIN_XCX)
                || type.equals(RechargeConstant.RECHARGE_WEIXIN_AFF) || type.equals(
                RechargeConstant.RECHARGE_WEIXIN_ZK_XCX)) {
            return PayPlatformContent.WeChat;
        } else if (type
                .equals(RechargeConstant.RECHARGE_PAY_ADAPAY)
                || type.equals(RechargeConstant.RECHARGE_PAY_ADAPAY_ZFB)) {
            return PayPlatformContent.HuiFu;
        } else {
            return PayPlatformContent.AliPay;
        }
    }

    /**
     * 交易类型转换
     *
     * @param type 充值订单类型
     * @return
     */
    public static Integer tranTransationType(Integer type) {
        Integer transationType;
        switch (type) {
            case RechargeConstant.recharge_pay:
                transationType = TransationLogConstant.BUSINESS_USER_RECHARGE_BALANCE;
                break;
            case RechargeConstant.recharge_returnBike:
                transationType = TransationLogConstant.BUSINESS_BALANCE_CYCLING;
                break;
            case RechargeConstant.recharge_Mem:
                transationType = TransationLogConstant.BUSINESS_BUY_MEM;
                break;
            case RechargeConstant.recharge_rideCard:
                transationType = TransationLogConstant.BUSINESS_BUY_RIDECARD;
                break;
            case RechargeConstant.recharge_vip:
                transationType = TransationLogConstant.BUSINESS_BUY_VIP;
                break;
            case RechargeConstant.recharge_meal:
                transationType = TransationLogConstant.BUSINESS_BUY_MEAL;
                break;
            default:
                transationType = TransationLogConstant.BUSINESS_USER_DEPOSIT;
                break;
        }
        return transationType;
    }

    @Override
    public String getOrder_weixin(String code, Integer accountId, Integer userId, Double money, String remark, Boolean deposit, Integer adAccountId, Integer rechargeType) {
        /**订单编号*/
        //String orderNO= WeixinPayUtil.getNonceStr(deposit);
        String orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_pay);
        if (deposit) {
            orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_deposit);
        }
        /**聚合支付校验*/
        adaPayService.checkIsAdaPay(accountId);

        //	WeixinPayConfig weixinPayConfig=checkWxPay(accountId, RechargeConstant.RECHARGE_WEIXIN_XCX,code);

			/*WeixinPayConfig weixinPayConfig;
			if (RechargeConstant.recharge_pay==rechargeType) {
				//余额充值进品牌账
				weixinPayConfig = checkWxPay(accountId, RechargeConstant.RECHARGE_WEIXIN_XCX,code);
			} else {
				weixinPayConfig = checkWxPayPlus(accountId, RechargeConstant.RECHARGE_WEIXIN_XCX,code, adAccountId);
			}*/
        /**欠款补交*/
        Boolean isLessMoney = false;
        User user = userService.getByUserId(userId);
        if (user != null && user.getRideMoney() > 0) {
            isLessMoney = true;
        }
        String goodRemark = GoodsConstant.GOODS_NAME_ORDER;
        WeixinPayConfig weixinPayConfig;
        if (RechargeConstant.recharge_pay == rechargeType) {
            /**欠款补交充值到对应区域*/
            if (isLessMoney) {
                RideLog rideLog = rideLogService.findLastByUserId(user.getUserId());
                if (rideLog != null) {
                    adAccountId = rideLog.getAccountId();
                    weixinPayConfig = checkWxPayPlus(accountId, RechargeConstant.RECHARGE_WEIXIN_XCX, code, rideLog.getAccountId());
                } else {
                    //无订单充值进品牌账
                    weixinPayConfig = checkWxPay(accountId, RechargeConstant.RECHARGE_WEIXIN_XCX, code);
                }
                goodRemark = GoodsConstant.GOODS_NAME_QKBJ;
            } else {
                //余额充值进品牌账
                weixinPayConfig = checkWxPay(accountId, RechargeConstant.RECHARGE_WEIXIN_XCX, code);
            }
        } else {
            RideLog rideLog = rideLogService.getByUserIdNotFinish(userId);
            if (rideLog != null) {
                adAccountId = rideLog.getAccountId();
            }
            weixinPayConfig = checkWxPayPlus(accountId, RechargeConstant.RECHARGE_WEIXIN_XCX, code, adAccountId);
        }
        /**记录用户第三方唯一id*/
        UserOtherBound userOtherBound = new UserOtherBound(userId, weixinPayConfig.getOpenId(), accountId, RechargeConstant.WXZFF_AUTH, UserConstant.OTHER_TYPE_WX);
        userOtherBoundService.insert(userOtherBound);

        /**基础校验*/
        money = order_base(userId, money, remark, deposit, orderNO, adAccountId, RechargeConstant.RECHARGE_WEIXIN_XCX, rechargeType);
        Account account = cacheService.getAccount(accountId);
        Account adAccount = cacheService.getAccount(adAccountId);
        /*生成订单信息提交微信*/
        WxPayDto tpWxPay = new WxPayDto();
        tpWxPay.setOpenId(weixinPayConfig.getOpenId());
        tpWxPay.setBody(account.getName() + "-" + adAccount.getName() + "-" + goodRemark);
        tpWxPay.setOrderId(orderNO);
        tpWxPay.setSpbillCreateIp("127.0.0.1");
        tpWxPay.setTotalFee(String.valueOf(money));
        String wxMchPay = cacheService.getBrandRemoteConfigValue(accountId, BrandConstant.WX_MCH_PAY_SWITCH);
        String result = WeixinPay.getPackage(weixinPayConfig, tpWxPay,Objects.equals(wxMchPay,"1"));
        String payApiType = Objects.equals("1",wxMchPay) ? PayApiTypeEnum.WECHAT_MCH_V3.getApiType() : PayApiTypeEnum.WECHAT_V2.getApiType();
        /**支付信息推送mq队列*/
        sendPayMsg(orderNO, RechargeConstant.PAY_CREATE,payApiType);
        return result;
    }

    @Override
    @Transactional
    public WeixinPayParam getOrder_app(Integer accountId, Integer userId, Double money, String remark, Boolean deposit, Integer adAccountId, Integer rechargeType) {
        /**订单编号*/
        //String orderNO= WeixinPayUtil.getNonceStr(deposit);
        String orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_pay);
        if (deposit) {
            orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_deposit);
        }
        /**聚合支付校验*/
        adaPayService.checkIsAdaPay(accountId);
        /**支付配置信息*/
        WeixinPayConfig weixinPayConfig = weixinPayConfigService.getByAccountId(accountId, 1);
        if (weixinPayConfig == null) {
            throw new BaseException("-2006", "该品牌微信支付未配置");
        }
        /**基础校验*/
        money = order_base(userId, money, remark, deposit, orderNO, adAccountId, RechargeConstant.RECHARGE_WEIXIN_APP, rechargeType);

        Account account = cacheService.getAccount(accountId);
        Account adAccount = cacheService.getAccount(adAccountId);
        /**生成订单信息提交微信*/
        WxPayDto tpWxPay = new WxPayDto();
        tpWxPay.setBody(account.getName() + "-" + adAccount.getName() + "-" + GoodsConstant.GOODS_NAME_ORDER);
        tpWxPay.setOrderId(orderNO);
        tpWxPay.setSpbillCreateIp("127.0.0.1");
        tpWxPay.setTotalFee(String.valueOf(money));
        WeixinPayParam wpp = WeixinPay.getPackage_app(weixinPayConfig, tpWxPay);
        /**支付信息推送mq队列*/
        sendPayMsg(orderNO, RechargeConstant.PAY_CREATE,null);
        return wpp;
    }

    /**
     * 微信小程序APP支付基础校验
     *
     * @param userId
     * @param money
     * @param remark
     * @param deposit
     * @param
     */
    @Override
    public Double order_base(Integer userId, Double money, String remark, Boolean deposit, String orderNO, Integer adAccountId, Integer type, Integer rechargeType) {
        /**查询用户信息*/
        User user = userService.getByUserId(userId);
        if (user == null) {
            throw new BaseException("-20005", "用户不存在");
        }

        /**判断是否是押金退还中*/
        if (deposit) {
            if (user.getDepositState() == 2) {
                throw new BaseException("-3003", "押金退还中");
            }
        }

        /*如果是押金，获取押金数额*/
        if (deposit) {
            /**是否提交免押*/
            AgentDepositVip agentDepositVip = agentDepositVipService.getByUserId(userId, adAccountId);
            if (agentDepositVip != null &&
                    DateTimeUtil.getTimeDF(agentDepositVip.getExpireDt() + " 23:59:59", DateTimeUtil.getNowTime()) < 0) {
                throw new BaseException("-120006", "存在生效中的免押卡");
            }
            if (user.getDepositState() == DepositStateConstant.DEPOSIT_STATE_SCORE || user.getDepositState() == DepositStateConstant.DEPOSIT_STATE_ZMXY) {
                throw new BaseException("-120007", "你已免押，无需在提交押金");
            }
            AdAccountDeposit adAccountDeposit = adAccountDepositService.getByAccountId(adAccountId);
            if (adAccountDeposit == null) {
                throw new BaseException("-3010", "押金未定义");
            } else {
                if (user.getDepositState() == 1) {
                    /**是否需要补交押金*/
                    if (adAccountDeposit.getDeposit() > user.getDepositMoney()) {
                        money = DoubleUtil.format(adAccountDeposit.getDeposit() - user.getDepositMoney());
                    } else {
                        throw new BaseException("-3009", "押金已经提交");
                    }
                } else if (user.getDepositState() == 0) {
                    money = (double) adAccountDeposit.getDeposit();
                } else {
                    throw new BaseException("-3032", "押金状态非法");
                }
                if (adAccountDeposit.getDeposit() == 0) {
                    throw new BaseException("-3051", "押金不能为0");
                }
            }
            /*信用免押单独处理*/
            if (RechargeConstant.recharge_exempt != rechargeType) {
                rechargeType = RechargeConstant.recharge_deposit;
            }
        }

        /**存在欠款金额，再次充值限制充值金额*/
        if ((money + user.getMoney() - user.getRideMoney()) < 0) {
            throw new BaseException("-20019", "当前存在欠款，请至少充值欠款金额");
        }
        //是否需要锁定订单金额，一段时间内不允许修改
        boolean lockOrder = false;
        String riderLogOrderNO = null;
        if (user.getRideMoney() > 0) {
            RideLog nOtPayByUserId = rideLogService.findNOtPayByUserId(userId);
            if (nOtPayByUserId != null) {
                adAccountId = nOtPayByUserId.getAccountId();
                redisService.add(RedisConstant.QKBJ_ACCOUNTID + userId, nOtPayByUserId.getAccountId().toString(), 10L );
                riderLogOrderNO = nOtPayByUserId.getOrderNO();
            }
            lockOrder = true;
            remark = "欠款补交";
        }
        if (user.getRideMoney() > 0 && (money + user.getMoney()) != user.getRideMoney()) {
            throw new BaseException("-20019", "当前存在欠款，请至少充值欠款金额");
        }
        if (adAccountId == null || adAccountId.equals(user.getAccountId())) {
            adAccountId = -1;
        }
        /**如果是充值结束订单,记录对应信息*/
        if (RechargeConstant.recharge_returnBike == rechargeType) {
            MachineBorrow machineBorrow = machineBorrowDao.getByUserId(userId);
            if (machineBorrow == null) {
                throw new BaseException("-3007", "不存在骑行记录");
            }
            lockOrder = true;
            riderLogOrderNO = machineBorrow.getOrderNO();
            String key = redisService.get(RedisConstant.USER_FINISH_PAY + userId);
            if (key != null) {
                String tmp = redisService.get(key);
                if (tmp != null) {
                    /**充值结束订单金额必须与缓存金额一致*/
                    BorrowReturnTer info = JSON.parseObject(tmp, BorrowReturnTer.class);
                    if (info.getPayMoney() != null && money.compareTo(info.getPayMoney()) != 0) {
                        throw new BaseException("-3071", "骑行订单金额发生变动，请重新发起还车");
                    }
                    RidePayLog ridePayLog = new RidePayLog();
                    ridePayLog.setPayOrderNO(orderNO);
                    ridePayLog.setRideOrderNO(machineBorrow.getOrderNO());
                    ridePayLog.setAddTime(new Date());
                    ridePayLog.setUpdateTime(new Date());
                    ridePayLog.setRideRemark(tmp);
                    ridePayLogService.insert(ridePayLog);
                }
            }
        }
        String nowTime = DateTimeUtil.getNowTime();
        if (lockOrder) {
            //当前支付的骑行订单金额锁定30秒不允许人工修改
            redisService.add(RedisConstant.LOCK_ORDER_MONEY + riderLogOrderNO, nowTime, 30);
        }
        Recharge recharge = new Recharge();
        recharge.setRechargeType(rechargeType);
        recharge.setType(type);
        recharge.setOrderNO(orderNO);
        recharge.setRechargeTime(nowTime);
        recharge.setUserId(userId);
        recharge.setState(0);
        recharge.setMoney(money);
        recharge.setRemark(remark);
        recharge.setDeposit(deposit);
        recharge.setAdAccountId(adAccountId);
        recharge.setBrandId(user.getAccountId());
        recharge.setPhone(user.getPhone());
        rechargeService.insert(recharge);

        String wxMchPay = cacheService.getBrandRemoteConfigValue(user.getAccountId(), BrandConstant.WX_MCH_PAY_SWITCH);
        int rechargePayTyp = Objects.equals("1",wxMchPay) ? 1 : 0 ;
        rechargePayTypeDao.addOne(new RechargePayType(orderNO,rechargePayTyp,""));
        return DoubleUtil.format(money / 100);
    }

    @Override
    @Transactional
    public String getMemberOrder_weixin(String code, User user, Integer memberFeeId, Integer adAccountId) {
        /**订单编号*/
        //String orderNO = "GXBIKEDM"+ DateTimeUtil.getDaformatyyyyMMddHHmmss(new Date()) + TenpayUtil.buildRandom(6);
        String orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_Mem);
        /**聚合支付校验*/
        adaPayService.checkIsAdaPay(user.getAccountId());
        /**支付配置信息(1:微信APP支付；2：微信小程序支付)*/

        //WeixinPayConfig weixinPayConfig=checkWxPay(user.getAccountId(), RechargeConstant.RECHARGE_WEIXIN_XCX,code);
        WeixinPayConfig weixinPayConfig = checkWxPayPlus(user.getAccountId(), RechargeConstant.RECHARGE_WEIXIN_XCX, code, adAccountId);
        checkIsByMem(user, adAccountId);

        Double money = getMemberOrder_base(RechargeConstant.RECHARGE_WEIXIN_XCX, user, adAccountId, orderNO, memberFeeId);
        Account account = cacheService.getAccount(user.getAccountId());
        Account adAccount = cacheService.getAccount(adAccountId);
        /**生成订单信息提交微信*/
        WxPayDto tpWxPay = new WxPayDto();
        tpWxPay.setOpenId(weixinPayConfig.getOpenId());
        tpWxPay.setBody(account.getName() + "-" + adAccount.getName() + "-" + GoodsConstant.GOODS_NAME_MEMBERORDER);
        tpWxPay.setOrderId(orderNO);
        tpWxPay.setSpbillCreateIp("127.0.0.1");
        tpWxPay.setTotalFee(String.valueOf(money));
        String wxMchPay = cacheService.getBrandRemoteConfigValue(user.getAccountId(), BrandConstant.WX_MCH_PAY_SWITCH);
        String result = WeixinPay.getPackage(weixinPayConfig, tpWxPay, Objects.equals(wxMchPay,"1"));
        String payApiType = Objects.equals("1",wxMchPay) ? PayApiTypeEnum.WECHAT_MCH_V3.getApiType() : PayApiTypeEnum.WECHAT_V2.getApiType();
        /**支付信息推送mq队列*/
        sendPayMsg(orderNO, RechargeConstant.PAY_CREATE,payApiType);
        return result;
    }

    @Override
    public Double getMemberOrder_base(Integer type, User user, Integer accountId, String orderNO, Integer memberFeeId) {
        Integer userId = user.getUserId();
        /** 查询会员费率 */
        MemberFee memberFee = memberFeeService.findById(memberFeeId);
        if (memberFee == null) {
            throw new BaseException("-130005", "未找到对应会员信息");
        }
        if (!memberFee.getAccountId().equals(accountId)) {
            throw new BaseException("-120008", "当前购买区域与套餐对应区域不一致，限制购买");
        }
        List<MemberLog> memberLogs = memberLogService.findByUserId(userId, accountId);
        if (memberLogs.size() > 0) {
            MemberLog memberLogDB = memberLogs.get(0);
            if (memberLogDB.getPayTime() != null &&
                    DateTimeUtil.getTimeDF(memberLogDB.getPayTime(), DateTimeUtil.getNowTime()) < 30) {
                throw new BaseException("-3041", "操作过于频繁，请稍等一会");
            }
        }
        /**免押会员开通记录*/
        MemberLog memberLog = new MemberLog();
        memberLog.setUserId(userId);
        memberLog.setAccountId(memberFee.getAccountId());
        memberLog.setMoney(memberFee.getMoney());
        memberLog.setBuyTime(DateTimeUtil.getNowTime());
        memberLog.setMemberFeeId(memberFeeId);
        memberLog.setOrderNO(orderNO);
        memberLog.setMemberState(0);
        memberLog.setRemark("用户微信支付");
        memberLogService.insert(memberLog);

        /** 记录资金变更*/
        Recharge recharge = new Recharge();
        recharge.setRechargeType(RechargeConstant.recharge_Mem);//免押会员
        recharge.setType(type);//0:app;1:微信APP；2：微信小程序;3:支付宝
        recharge.setOrderNO(orderNO);
        recharge.setRechargeTime(DateTimeUtil.getNowTime());
        recharge.setUserId(userId);
        recharge.setState(0);
        recharge.setDeposit(false);
        recharge.setMoney(memberFee.getMoney());
        recharge.setBrandId(user.getAccountId());
        recharge.setAdAccountId(memberFee.getAccountId());
        recharge.setRemark("免押会员付费， " + "会员类型：" + memberFeeId);
        recharge.setPhone(user.getPhone());
        rechargeService.insert(recharge);

        String wxMchPay = cacheService.getBrandRemoteConfigValue(user.getAccountId(), BrandConstant.WX_MCH_PAY_SWITCH);
        int rechargePayTyp = Objects.equals("1",wxMchPay) ? 1 : 0 ;
        rechargePayTypeDao.addOne(new RechargePayType(orderNO,rechargePayTyp,""));
        return memberFee.getMoney() / 100;
    }

    @Override
    @Transactional
    public String getRideCardOrder_weixin(String code, User user, Integer rideCardId, Integer adAccountId) {
        /**订单编号*/
        //String orderNO = "GXBIKERC"+ DateTimeUtil.getDaformatyyyyMMddHHmmss(new Date()) + TenpayUtil.buildRandom(6);
        String orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_rideCard);
        /**聚合支付校验*/
        adaPayService.checkIsAdaPay(user.getAccountId());
        /**支付配置信息(1:微信APP支付；2：微信小程序支付)*/
		/*WeixinPayConfig weixinPayConfig=weixinPayConfigService.getByAccountId(user.getAccountId(),2);
		if(weixinPayConfig==null){
			throw new BaseException("-2006","该品牌微信支付未配置");
		}

		*//**获取微信openId*//*
		String openId=MyX509TrustManager.getOpenId(code,weixinPayConfig);
		if(openId==null){
			throw new BaseException("-3026","获取微信openId失败");
		}*/
        //WeixinPayConfig weixinPayConfig=checkWxPay(user.getAccountId(), RechargeConstant.RECHARGE_WEIXIN_XCX,code);
        WeixinPayConfig weixinPayConfig = checkWxPayPlus(user.getAccountId(), RechargeConstant.RECHARGE_WEIXIN_XCX, code, adAccountId);
        Double money = getRideCardOrder_base(RechargeConstant.RECHARGE_WEIXIN_XCX, user, rideCardId, orderNO, adAccountId);
        Account account = cacheService.getAccount(user.getAccountId());
        Account adAccount = cacheService.getAccount(adAccountId);
        /**生成订单信息提交微信*/
        WxPayDto tpWxPay = new WxPayDto();
        tpWxPay.setOpenId(weixinPayConfig.getOpenId());
        tpWxPay.setBody(account.getName() + "-" + adAccount.getName() + "-" + GoodsConstant.GOODS_NAME_RIDECARDORDER);
        tpWxPay.setOrderId(orderNO);
        tpWxPay.setSpbillCreateIp("127.0.0.1");
        tpWxPay.setTotalFee(String.valueOf(money));
        String wxMchPay = cacheService.getBrandRemoteConfigValue(user.getAccountId(), BrandConstant.WX_MCH_PAY_SWITCH);
        String result = WeixinPay.getPackage(weixinPayConfig, tpWxPay, Objects.equals(wxMchPay,"1"));
        String payApiType = Objects.equals("1",wxMchPay) ? PayApiTypeEnum.WECHAT_MCH_V3.getApiType() : PayApiTypeEnum.WECHAT_V2.getApiType();
        /**支付信息推送mq队列*/
        sendPayMsg(orderNO, RechargeConstant.PAY_CREATE,payApiType);
        return result;
    }

    @Override
    public Double getRideCardOrder_base(Integer type, User user, Integer rideCardId, String orderNO, Integer adAccountId) {
        Integer userId = user.getUserId();
        /**查询骑行卡信息*/
        RideCard rideCard = rideCardService.getById(rideCardId);
        if (rideCard == null) {
            throw new BaseException("-120002", "骑行卡不存在");
        }
        if (!rideCard.getAccountId().equals(adAccountId)) {
            throw new BaseException("-120008", "当前购买区域与套餐对应区域不一致，限制购买");
        }
        /**删除未支付的订单*/
        //rideCardUserService.delNotPay(userId);

        /**获取用户最新创建的骑行卡订单,如果创建时间距离当前不超过10秒*/
        RideCardUser rideCardUserDB = rideCardUserService.queryByTime(userId);
        if (rideCardUserDB != null && DateTimeUtil.getTimeDF(rideCardUserDB.getBuyTime(), DateTimeUtil.getNowTime()) <= 10) {
            throw new BaseException("-120005", "操作过于频繁，请稍后重试");
        }
        /**查询是否有生效中的骑行卡*/
        //List<RideCardUser> rideCardUsers=rideCardUserService.getRideVaildCard(user,rideCard.getAccountId(),rideCard.getFeeId());

        List<RideCardUser> rideCardUsers = rideCardUserService.checkValid(user.getUserId());
        List<Integer> accountIds = cardAccountBoundService.getAccountId(adAccountId, user.getAccountId(),
                CardTypeConstant.TYPE_RIDECARD);

        if (rideCardUsers.size() > 0) {
            for (RideCardUser r : rideCardUsers) {
                if (rideCard.getFeeId().equals(r.getFeeId()) && accountIds.contains(r.getAccountId())) {
                    throw new BaseException("-120003", "购买失败,存在生效中的骑行卡");
                }
            }
        }

        /**添加记录*/
        RideCardUser rideCardUser = new RideCardUser();

        rideCardUser.setUserId(userId);
        rideCardUser.setRideCardId(rideCardId);
        rideCardUser.setAccountId(rideCard.getAccountId());
        rideCardUser.setStartDate(DateTimeUtil.getNowTimeYMD());
        rideCardUser.setEndDate(DateTimeUtil.getRideCardEndDate(rideCard.getType(),rideCard.getVaildDays()));
        rideCardUser.setOrderNO(orderNO);

        rideCardUserService.insert(rideCardUser);

        /**订单表*/
        Recharge recharge = new Recharge();
        recharge.setRechargeType(RechargeConstant.recharge_rideCard);//0:押金;1:充值;2:免押会员;3:骑行会员
        recharge.setType(type);//0:app;1:微信APP；2：微信小程序;3:支付宝
        recharge.setOrderNO(orderNO);
        recharge.setRechargeTime(DateTimeUtil.getNowTime());
        recharge.setUserId(userId);
        recharge.setState(0);
        recharge.setDeposit(false);
        recharge.setMoney(rideCard.getMoney());
        recharge.setAdAccountId(rideCard.getAccountId());
        recharge.setBrandId(user.getAccountId());
        recharge.setRemark("骑行会员付费， " + "会员类型：" + rideCard.getType());
        recharge.setPhone(user.getPhone());
        rechargeService.insert(recharge);

        String wxMchPay = cacheService.getBrandRemoteConfigValue(user.getAccountId(), BrandConstant.WX_MCH_PAY_SWITCH);
        int rechargePayTyp = Objects.equals("1",wxMchPay) ? 1 : 0 ;
        rechargePayTypeDao.addOne(new RechargePayType(orderNO,rechargePayTyp,""));
        return rideCard.getMoney() / 100;
    }

    @Override
    public WeixinPayParam getMemberOrder_app(User user, Integer memberFeeId, Integer adAccountId) {
        /**订单编号*/
        //String orderNO = "UQBIKEDM"+ DateTimeUtil.getDaformatyyyyMMddHHmmss(new Date()) + TenpayUtil.buildRandom(6);
        String orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_Mem);
        /**聚合支付校验*/
        adaPayService.checkIsAdaPay(user.getAccountId());
        /**支付配置信息(1:微信APP支付；2：微信小程序支付)*/
        WeixinPayConfig weixinPayConfig = weixinPayConfigService.getByAccountId(user.getAccountId(),
                RechargeConstant.RECHARGE_WEIXIN_APP);
        if (weixinPayConfig == null) {
            throw new BaseException("-2006", "该品牌微信支付未配置");
        }
		/*User userDB= userService.getByUserId(user.getUserId());
		AdAccountDeposit adAccountDeposit= adAccountDepositService.getByAccountId(adAccountId);
		if(adAccountDeposit!=null&&((userDB.getDepositState()== DepositStateConstant.DEPOSIT_STATE_PAY
				&&userDB.getDepositMoney()>=adAccountDeposit.getDeposit())||userDB.getDepositState()==DepositStateConstant.DEPOSIT_STATE_SCORE)){
			throw new BaseException("-3009","已交押金");
		}*/
        checkIsByMem(user, adAccountId);
        Double money = getMemberOrder_base(RechargeConstant.RECHARGE_WEIXIN_APP, user, adAccountId, orderNO, memberFeeId);
        Account account = cacheService.getAccount(user.getAccountId());
        Account adAccount = cacheService.getAccount(adAccountId);
        /**生成订单信息提交微信*/
        WxPayDto tpWxPay = new WxPayDto();
        tpWxPay.setBody(account.getName() + "-" + adAccount.getName() + "-" + GoodsConstant.GOODS_NAME_MEMBERORDER);
        tpWxPay.setOrderId(orderNO);
        tpWxPay.setSpbillCreateIp("127.0.0.1");
        tpWxPay.setTotalFee(String.valueOf(money));

        WeixinPayParam wpp = WeixinPay.getPackage_app(weixinPayConfig, tpWxPay);
        /**支付信息推送mq队列*/
        sendPayMsg(orderNO, RechargeConstant.PAY_CREATE,null);
        return wpp;
    }

    @Override
    public WeixinPayParam getRideCardOrder_app(User user, Integer rideCardId, Integer adAccountId) {
        /**订单编号*/
        //String orderNO = "UQBIKERC"+ DateTimeUtil.getDaformatyyyyMMddHHmmss(new Date()) + TenpayUtil.buildRandom(6);
        String orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_rideCard);
        /**聚合支付校验*/
        adaPayService.checkIsAdaPay(user.getAccountId());
        /**支付配置信息(1:微信APP支付；2：微信小程序支付)*/
        WeixinPayConfig weixinPayConfig = weixinPayConfigService.getByAccountId(user.getAccountId(),
                RechargeConstant.RECHARGE_WEIXIN_APP);
        if (weixinPayConfig == null) {
            throw new BaseException("-2006", "该品牌微信支付未配置");
        }

        Double money = getRideCardOrder_base(RechargeConstant.RECHARGE_WEIXIN_APP, user, rideCardId, orderNO, adAccountId);
        Account account = cacheService.getAccount(user.getAccountId());
        Account adAccount = cacheService.getAccount(adAccountId);
        /**生成订单信息提交微信*/
        WxPayDto tpWxPay = new WxPayDto();
        tpWxPay.setBody(account.getName() + "-" + adAccount.getName() + "-" + GoodsConstant.GOODS_NAME_RIDECARDORDER);
        tpWxPay.setOrderId(orderNO);
        tpWxPay.setSpbillCreateIp("127.0.0.1");
        tpWxPay.setTotalFee(String.valueOf(money));

        WeixinPayParam wpp = WeixinPay.getPackage_app(weixinPayConfig, tpWxPay);
        /**支付信息推送mq队列*/
        sendPayMsg(orderNO, RechargeConstant.PAY_CREATE, null);
        return wpp;
    }

    @Override
    public String getVipOrder_weixin(String code, User user, Integer vipId, Integer adAccountId) {
        /**订单编号*/
        //String orderNO = "UQBIKEVIP"+ DateTimeUtil.getDaformatyyyyMMddHHmmss(new Date()) + TenpayUtil.buildRandom(6);
        String orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_vip);
        /**聚合支付校验*/
        adaPayService.checkIsAdaPay(user.getAccountId());
        /**支付配置信息(1:微信APP支付；2：微信小程序支付)*/
		/*WeixinPayConfig weixinPayConfig=weixinPayConfigService.getByAccountId(user.getAccountId(),2);
		if(weixinPayConfig==null){
			throw new BaseException("-2006","该品牌微信支付未配置");
		}

		*//**获取微信openId*//*
		String openId=MyX509TrustManager.getOpenId(code,weixinPayConfig);
		if(openId==null){
			throw new BaseException("-3026","获取微信openId失败");
		}*/
        //WeixinPayConfig weixinPayConfig=checkWxPay(user.getAccountId(), RechargeConstant.RECHARGE_WEIXIN_XCX,code);
        WeixinPayConfig weixinPayConfig = checkWxPayPlus(user.getAccountId(), RechargeConstant.RECHARGE_WEIXIN_XCX, code, adAccountId);
        Double money = getVipOrder_base(RechargeConstant.RECHARGE_WEIXIN_XCX, user, vipId, orderNO, adAccountId);
        Account account = cacheService.getAccount(user.getAccountId());
        Account adAccount = cacheService.getAccount(adAccountId);
        /**生成订单信息提交微信*/
        WxPayDto tpWxPay = new WxPayDto();
        tpWxPay.setOpenId(weixinPayConfig.getOpenId());
        tpWxPay.setBody(account.getName() + "-" + adAccount.getName() + "-" + GoodsConstant.GOODS_NAME_VIPORDER);
        tpWxPay.setOrderId(orderNO);
        tpWxPay.setSpbillCreateIp("127.0.0.1");
        tpWxPay.setTotalFee(String.valueOf(money));
        String wxMchPay = cacheService.getBrandRemoteConfigValue(user.getAccountId(), BrandConstant.WX_MCH_PAY_SWITCH);
        String result = WeixinPay.getPackage(weixinPayConfig, tpWxPay, Objects.equals(wxMchPay,"1"));
        String payApiType = Objects.equals("1",wxMchPay) ? PayApiTypeEnum.WECHAT_MCH_V3.getApiType() : PayApiTypeEnum.WECHAT_V2.getApiType();
        /**支付信息推送mq队列*/
        sendPayMsg(orderNO, RechargeConstant.PAY_CREATE,payApiType);
        return result;
    }

    @Override
    public WeixinPayParam getVipOrder_app(User user, Integer vipId, Integer adAccountId) {
        /**订单编号*/
        //String orderNO = "GXBIKEVIP"+ DateTimeUtil.getDaformatyyyyMMddHHmmss(new Date()) + TenpayUtil.buildRandom(6);
        String orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_vip);
        /**聚合支付校验*/
        adaPayService.checkIsAdaPay(user.getAccountId());
        /**支付配置信息(1:微信APP支付；2：微信小程序支付)*/
        WeixinPayConfig weixinPayConfig = weixinPayConfigService.getByAccountId(user.getAccountId(),
                RechargeConstant.RECHARGE_WEIXIN_APP);
        if (weixinPayConfig == null) {
            throw new BaseException("-2006", "该品牌微信支付未配置");
        }
        //0:app;1:微信APP；2：微信小程序;3:支付宝
        Double money = getVipOrder_base(RechargeConstant.RECHARGE_WEIXIN_APP, user, vipId, orderNO, adAccountId);
        Account account = cacheService.getAccount(user.getAccountId());
        Account adAccount = cacheService.getAccount(adAccountId);
        /**生成订单信息提交微信*/
        WxPayDto tpWxPay = new WxPayDto();
        tpWxPay.setBody(account.getName() + "-" + adAccount.getName() + "-" + GoodsConstant.GOODS_NAME_VIPORDER);
        tpWxPay.setOrderId(orderNO);
        tpWxPay.setSpbillCreateIp("127.0.0.1");
        tpWxPay.setTotalFee(String.valueOf(money));

        WeixinPayParam wpp = WeixinPay.getPackage_app(weixinPayConfig, tpWxPay);
        /**支付信息推送mq队列*/
        sendPayMsg(orderNO, RechargeConstant.PAY_CREATE,null);
        return wpp;
    }

    /**
     * 汇付订单
     *
     * @param recharge
     * @param adaPayId
     * @param fee
     */
    public void handelAdaPay(Recharge recharge, String adaPayId, String fee, String dateTime) {
        String order_no = recharge.getOrderNO();
        boolean cashAll = false;
        String cashButton = redisService.get(RedisConstant.ADAPAY_PAY_CASH + order_no);
        if (cashButton != null) {
            cashAll = Boolean.valueOf(cashButton);
        }
        /**分账订单更新已支付*/
        AdaPayLog adaPayLog = adaPayLogService.getByOrderNO(order_no);
        if (adaPayLog != null && adaPayLog.getState().equals(AdaPayConstant.ADAPAY_LOG_DEFAULT)) {
            String string = redisService.get(RedisConstant.ADAPAY_PAY_MODEL + order_no);
            Integer model = string == null ? 0 : Integer.valueOf(string);
            AdaPayLog adaPayLogDB = new AdaPayLog();
            adaPayLogDB.setOrderNO(order_no);
            adaPayLogDB.setAdaPayId(adaPayId);
            adaPayLogDB.setUpdateTime(DateTimeUtil.StringToDateTime(dateTime));
            String depositAccount = adaPayService.getDepositAccount(recharge.getBrandId());
            // 欠款补交新版实时分账标识
            String tag = redisService.get(RedisConstant.QKBJ_CASH_TAG + recharge.getOrderNO());
            /**实时分账订单状态回调即为分账完成*/
            if (model.equals(AdaPayConstant.ADAPAY_MODEL_NOW) && (
                    adaPayLog.getType().equals(
                            RechargeConstant.recharge_returnBike) || RechargeConstant.recharge_vip == (adaPayLog.getType()) ||
                            (RechargeConstant.recharge_QKBJ == (adaPayLog.getType()) && Objects.equals(delayPayQKBJSwitch.getModel(),DelayPayQKBJSwitch.REAL_TIME))
                            || RechargeConstant.recharge_Mem == (adaPayLog.getType()) || RechargeConstant.recharge_rideCard == (adaPayLog.getType())
                            || RechargeConstant.recharge_meal == (adaPayLog.getType()) || (RechargeConstant.recharge_deposit == (adaPayLog.getType()) && StringUtils
                            .isNotBlank(depositAccount)) || cashAll)) {
                // 老版本触发分账
                adaPayLogDB.setState(AdaPayConstant.ADAPAY_LOG_CASH);
                adaPayLogDB.setCashMoney(adaPayLog.getMoney());
                /**实时分账分账订单号就是创建订单订单号*/
                adaPayLogDB.setCashNO(recharge.getOrderNO());
//                /**记录分账详细*/
//                String details = redisService.get(RedisConstant.ADAPAY_PAY_DETAIL + order_no);
//                if (details != null) {
//                    List<UserAdaPayLog> logs = JSON.parseArray(details, UserAdaPayLog.class);
//                    for (UserAdaPayLog u : logs) {
//                        u.setAddTime(DateTimeUtil.StringToDateTime(dateTime));
//                        if (u.getMainUser() == 1) {
//                            BigDecimal bigDecimal = new BigDecimal(fee);
//                            BigDecimal result= bigDecimal.multiply(new BigDecimal(100));
//                            u.setFee(result.intValue());
//                        }
//                    }
//                    userAdaPayLogService.addBatch(logs);
//                    /**清除Redis数据*/
//                    redisService.del(RedisConstant.ADAPAY_PAY_DETAIL + order_no);
//                }
                List<UserAdaPayLog> userAdaPayLogList = userAdaPayLogTempService.getListByOrderNO(order_no);

                /**灰度发布添加需求*/
                if (userAdaPayLogList.isEmpty()){
                    String details = redisService.get(RedisConstant.ADAPAY_PAY_DETAIL + order_no);
                    if (details != null) {
                        userAdaPayLogList = JSON.parseArray(details, UserAdaPayLog.class);
                        redisService.del(RedisConstant.ADAPAY_PAY_DETAIL + order_no);
                    }
                }

                if (!userAdaPayLogList.isEmpty()) {
                    for (UserAdaPayLog userAdaPayLog : userAdaPayLogList) {
                        userAdaPayLog.setAddTime(DateTimeUtil.StringToDateTime(dateTime));
                        if (userAdaPayLog.getMainUser() == 1){
                            BigDecimal bigDecimal = new BigDecimal(fee);
                            BigDecimal result= bigDecimal.multiply(new BigDecimal(100));
                            userAdaPayLog.setFee(result.intValue());
                        }
                    }
                    // 插入 userAdapaylog
                    userAdaPayLogService.addBatch(userAdaPayLogList);
                    // 清除临时表
                    userAdaPayLogTempService.deleteByOrderNO(order_no);
                }

            } else {
                adaPayLogDB.setState(AdaPayConstant.ADAPAY_LOG_PAY);
            }
            adaPayLogService.edit(adaPayLogDB);
        } else {
            log.warn("分账订单不存在" + order_no);
        }
    }

    @Override
    public void pay(Recharge recharge, String out_trade_no, String transaction_id, String dateTime, String fee) {

        Integer userId = recharge.getUserId();
        /*
          如果是充值结束订单，判断最近（可配置时间）是否存在支付成功的充值结束订单
          如果存在，则视为重复支付，对回调订单进行记录
         */
        if (hasRecentChargeReturnBike(userId)) {
            log.warn("用户{}存在最近支付成功的充值结束订单，订单号：{}", userId, out_trade_no);
        }
        if (Integer.valueOf(RechargeConstant.recharge_returnBike).equals(recharge.getRechargeType())) {
            //到这里就默认已支付，后面不管是否成功都应该锁，避免重复支付充值结束订单
            redisService.add(RedisConstant.RECHARGE_RETURNBIKE_PAYMENT_FINISH + userId, recharge.getOrderNO(), chargeReturnBikeGapSeconds);
        }

        Recharge rechargeNew = new Recharge();
        rechargeNew.setOrderNO(recharge.getOrderNO());
        rechargeNew.setPayTime(dateTime);
        rechargeNew.setState(1);
        rechargeService.update(rechargeNew);
        /**查询用户信息*/
        User user = userService.getByUserId(recharge.getUserId());
        if (RechargeConstant.RECHARGE_WEIXIN_XCX.equals(recharge.getType()) || RechargeConstant.RECHARGE_WEIXIN_AFF.equals(recharge.getType()) || RechargeConstant.RECHARGE_WEIXIN_APP.equals(recharge.getType())) {
            WeixinPayConfig weixinPayConfig = weixinPayConfigService.getByAccountId(recharge.getAdAccountId(), 2);
            if (weixinPayConfig == null || (recharge.getRechargeType().equals(RechargeConstant.recharge_pay) && user.getRideMoney() == 0)) {
                //没有区域配置或者充值进品牌账户
                weixinPayConfig = weixinPayConfigService.getByAccountId(user.getAccountId(), 2);
            }
            rechargeMerchantService.insert(new RechargeMerchant(recharge.getOrderNO(), recharge.getBrandId(), recharge.getAdAccountId(), weixinPayConfig.getPartner(), DateUtil.parse(dateTime)));
        }
        /**默认为充值押金*/
        if (recharge.getRechargeType() == null) {
            recharge.setRechargeType(0);
        }
        if (recharge.getType().equals(RechargeConstant.RECHARGE_PAY_ADAPAY) || recharge.getType().equals(RechargeConstant.RECHARGE_PAY_ADAPAY_ZFB)) {
            handelAdaPay(recharge, out_trade_no, fee, dateTime);
        }
        UserToAgent userToAgent = userToAgentDao.getByUserId(user.getUserId());
        Integer firstId = recharge.getAdAccountId();
        if (userToAgent != null) {
            firstId = userToAgent.getFirstId();
        } else {
            if (recharge.getAdAccountId() != -1) {
                userToAgent = new UserToAgent();
                userToAgent.setFirstId(recharge.getAdAccountId());
                userToAgent.setUpdateDt(dateTime);
                userToAgent.setAccountId(recharge.getAdAccountId());
                userToAgent.setUserId(user.getUserId());
                userToAgentDao.insert(userToAgent);
                userToAgentDao.insertBindTime(userToAgent);
            }
        }
        /**金额类型*/
        Integer capitalType;
        /**业务类型*/
        Integer businessType;
        /**备注*/
        String remark;
        /**变动前金额*/
        Long changeStartMoney;
        /**变动后金额*/
        Long changeEndMoney;
        /**充值交易类型*/
        Integer transactionType;
        /**流水类型，默认充值*/
        Integer changeType = PayPlatformContent.PAY_RECHARGE;
        /**免押会员*/
        if (recharge.getRechargeType().equals(RechargeConstant.recharge_Mem)) {//免押会员
            capitalType = PayPlatformContent.PAY_CARD;
            businessType = BusinessConstant.BUSINESS_BUY_MEM;
            remark = "免押会员购买";
            changeStartMoney = 0L;
            changeEndMoney = 0L;
            transactionType = TransationLogConstant.BUSINESS_BUY_MEM;
            MemberLog mb = memberLogService.findByOrderNo(recharge.getOrderNO());
            /** 查询会员费率 */
            MemberFee memberFee = memberFeeService.findById(mb.getMemberFeeId());
            if (memberFee != null) {
                /**默认从当前时间开始计算失效时间*/
                String endDate = DateTimeUtil.getServiceEndDate(null, memberFee.getType());
                /**用户已购买，则时间累加*/
                AgentDepositVip agentDepositVip = agentDepositVipService.getByUserId(user.getUserId(), mb.getAccountId());
                if (agentDepositVip != null) {
                    endDate = DateTimeUtil.getServiceEndDate(agentDepositVip.getExpireDt(), memberFee.getType());
                } else {
                    agentDepositVip = new AgentDepositVip();
                }
                agentDepositVip.setAccountId(mb.getAccountId());
                agentDepositVip.setExpireDt(endDate);
                agentDepositVip.setUserId(user.getUserId());
                agentDepositVipService.insert(agentDepositVip);

                if (endDate != null) {
                    /** 会员开通记录信息更新 */
                    mb.setExpireTime(endDate);
                    mb.setMemberState(1);
                    mb.setPayTime(dateTime);
                    memberLogService.update(mb);
                }
                addUserAccountLog(user, dateTime, recharge.getMoney(), RechargeConstant.MONEY_TYPE_REAL, RechargeConstant.RECHARGE_TYPE_CONSUMPTION, "免押会员开通费用");
                /**区域业务共享，查询是否存在绑定多区域共享免押*/
                List<AccountBusBound> list = accountBusBoundService.getByAccountId(mb.getAccountId(),
                        RechargeConstant.recharge_Mem);
                if (list.size() > 0) {
                    for (AccountBusBound accountBusBound : list) {
                        agentDepositVip.setAccountId(accountBusBound.getTargetAccountId());
                        agentDepositVip.setExpireDt(endDate);
                        agentDepositVip.setUserId(user.getUserId());
                        agentDepositVipService.insert(agentDepositVip);
                    }
                }
                Account account = accountService.getByAccountId(memberFee.getAccountId());

                /**日志数据异步入库*/
                PayCardLog payCardLog = new PayCardLog(user.getUserId(), user.getPhone(), user.getName(), memberFee.getAccountId()
                        , user.getAccountId(), account.getName(), recharge.getOrderNO(),
                        BusinessConstant.BUSINESS_BUY_MEM, memberFee.getName(),
                        PayCardLogContent.deposit_card, memberFee.getType(), tranbusinessType(recharge.getType()), recharge.getMoney().longValue(), DateTimeUtil.StringToDateTime(dateTime)
                        , "免押卡充值");
                pushMsgLogService.sendPushLog(JSON.toJSONString(payCardLog), TableNameConstant.PAYCARDLOG);

                addRideFeelog(recharge.getOrderNO(), memberFee.getAccountId(), user
                        , recharge.getMoney().intValue(), recharge, RechargeConstant.recharge_Mem);

                // 插入用户操作日志
                userOpLogService.insertSingle(UserOpLog.builder()
                        .accountId(user.getAccountId())
                        .opUser(user.getName())
                        .opUserPhone(user.getPhone())
                        .targetUser(user.getName())
                        .targetUserPhone(user.getPhone())
                        .operation("免押卡")
                        .opType("用户购买")
                        .opPlatform(OperationPlatform.CLIENT.code)
                        .opTime(LocalDateTime.now())
                        .result(true)
                        .detail("免押卡名称: " + memberFee.getName() + "\n免押卡ID: " + memberFee.getMemberFeeId())
                        .build());
            } else {
                LogUtil.warn("找不到免押会员费率");
            }

        } else if (recharge.getRechargeType().equals(RechargeConstant.recharge_rideCard)) {
            capitalType = PayPlatformContent.PAY_CARD;
            businessType = BusinessConstant.BUSINESS_BUY_RIDECARD;
            remark = "骑行会员购买";
            changeStartMoney = 0L;
            changeEndMoney = 0L;
            transactionType = TransationLogConstant.BUSINESS_BUY_RIDECARD;
            //骑行会员
            /**查询用户购买订单*/
            RideCardUser rideCardUser = rideCardUserService.getByOrderNO(recharge.getOrderNO());
            if (rideCardUser != null) {
                /**更新状态为支付*/
                rideCardUserService.updatePay(recharge.getOrderNO(), dateTime);
                addUserAccountLog(user, dateTime, recharge.getMoney(), RechargeConstant.MONEY_TYPE_REAL, RechargeConstant.RECHARGE_TYPE_CONSUMPTION, "骑行会员开通费用");

            }

            Account account = accountService.getByAccountId(rideCardUser.getAccountId());
            RideCard rideCard = rideCardService.getById(rideCardUser.getRideCardId());

            /**日志数据异步入库*/
            PayCardLog payCardLog = new PayCardLog(user.getUserId(), user.getPhone(), user.getName(), rideCardUser.getAccountId()
                    , user.getAccountId(), account.getName(), recharge.getOrderNO(),
                    BusinessConstant.BUSINESS_BUY_RIDECARD, rideCard.getName(), PayCardLogContent.ride_card, rideCard.getType(),
                    tranbusinessType(recharge.getType()), recharge.getMoney().longValue(), DateTimeUtil.StringToDateTime(dateTime)
                    , "骑行卡卡充值");
            pushMsgLogService.sendPushLog(JSON.toJSONString(payCardLog), TableNameConstant.PAYCARDLOG);
            addRideFeelog(recharge.getOrderNO(), rideCardUser.getAccountId(), user
                    , recharge.getMoney().intValue(), recharge, RechargeConstant.recharge_rideCard);

            // 插入用户操作日志
            userOpLogService.insertSingle(UserOpLog.builder()
                    .accountId(user.getAccountId())
                    .opUser(user.getName())
                    .opUserPhone(user.getPhone())
                    .targetUser(user.getName())
                    .targetUserPhone(user.getPhone())
                    .operation("骑行卡套餐变动")
                    .opType("用户购买")
                    .opPlatform(OperationPlatform.CLIENT.code)
                    .opTime(LocalDateTime.now())
                    .result(true)
                    .detail("套餐名称: " + rideCard.getName() + "\n套餐ID: " + rideCard.getRideCardId())
                    .build());
        } else if (recharge.getRechargeType().equals(RechargeConstant.recharge_pay) || recharge.getRechargeType().equals(RechargeConstant.recharge_deposit)) {
            capitalType = PayPlatformContent.PAY_BALANCE;
            businessType = BusinessConstant.BUSINESS_USER_RECHARGE_BALANCE;
            remark = "充值";
            //changeStartMoney=user.getMoney().longValue();
            UserAccountMoney userAccountMoney = userAccountMoneyService.getByAccountId(user.getUserId(), BalanceLogChangeTypeContent.capitalType_balance, recharge.getAdAccountId());
            changeStartMoney = userAccountMoney == null ? 0 : userAccountMoney.getMoney();
            changeEndMoney = 0L;
            transactionType = TransationLogConstant.BUSINESS_USER_RECHARGE_BALANCE;
            //充值押金或者余额
            /**判断是否是押金*/
            if (recharge.getDeposit()) {
                /**更新押金标识*/
                userService.updateDepositAndMoney(user.getUserId(), 1, recharge.getMoney());

                /**添加金额变动日志*/
                addUserAccountLog(user, dateTime, recharge.getMoney(), RechargeConstant.MONEY_TYPE_REAL, RechargeConstant.RECHARGE_TYPE_RECHARGE, "押金");


                /**记录押金充值日志，用于日后押金退还*/
                WeixinDepositLog weixinDepositLog = new WeixinDepositLog();
                weixinDepositLog.setAccountId(user.getAccountId());
                weixinDepositLog.setType(recharge.getType());
                weixinDepositLog.setUserId(user.getUserId());
                weixinDepositLog.setDepositMoney(recharge.getMoney());
                weixinDepositLog.setAddTime(dateTime);
                weixinDepositLog.setOut_trade_no(out_trade_no);
                weixinDepositLog.setTransaction_id(transaction_id);
                weixinDepositLog.setRemark("用户提交的押金");

                weixinDepositLogService.insert(weixinDepositLog);

                capitalType = PayPlatformContent.PAY_DEPOSIT;
                businessType = BusinessConstant.BUSINESS_USER_DEPOSIT;
                remark = "押金";
                changeStartMoney = user.getDepositMoney().longValue();
                userAccountMoney = userAccountMoneyService.getByAccountId(user.getUserId(), BalanceLogChangeTypeContent.capitalType_deposit, recharge.getAdAccountId());
                changeStartMoney = userAccountMoney == null ? 0 : userAccountMoney.getMoney();
                changeEndMoney = changeStartMoney + recharge.getMoney().longValue();
                transactionType = TransationLogConstant.BUSINESS_USER_DEPOSIT;
                addBalanceChange(user, recharge, dateTime, capitalType, businessType
                        , changeStartMoney, recharge.getMoney().longValue(), changeEndMoney, "押金", PayPlatformContent.PAY_RECHARGE);
                machineService.addBalanceChange(user, recharge.getOrderNO(), recharge.getAdAccountId(), DateTimeUtil.StringToDateTime(dateTime)
                                .getTime(), capitalType, businessType
                        , changeStartMoney, recharge.getMoney().longValue(), "押金", PayPlatformContent.PAY_RECHARGE);

                // 插入用户操作日志
                userOpLogService.insertSingle(UserOpLog.builder()
                        .accountId(user.getAccountId())
                        .opUser(user.getName())
                        .opUserPhone(user.getPhone())
                        .targetUser(user.getName())
                        .targetUserPhone(user.getPhone())
                        .operation("押金变动")
                        .opType("支付押金")
                        .opPlatform(OperationPlatform.CLIENT.code)
                        .opTime(LocalDateTime.now())
                        .result(true)
                        .detail("变动金额: " + recharge.getMoney() / 100d + "元")
                        .build());
            } else {
                changeEndMoney = changeStartMoney + recharge.getMoney().longValue();
                /**获取订单创建是所在区域id*/
                Integer agentId = recharge.getAdAccountId();
                if (agentId != null && user.getRideMoney() == 0) {
                    /**查询是否存在充值赠送活动*/
                    List<RechargeGive> list = rechargeGiveService.getByAccountId(agentId);
                    if (list.size() > 0) {
                        for (RechargeGive rechargeGive : list) {
                            /**符合赠送条件，取最高赠送，跳出循环*/
                            if (recharge.getMoney() >= rechargeGive.getBaseMoney() && rechargeGive.getBaseMoney() > 0) {
                                /**记录充值赠送日志*/
                                RechargeGiveLog rechargeGiveLog = new RechargeGiveLog();
                                rechargeGiveLog.setAccountId(rechargeGive.getAccountId());
                                rechargeGiveLog.setUserId(recharge.getUserId());
                                rechargeGiveLog.setRechargeMoney(recharge.getMoney().intValue());
                                rechargeGiveLog.setRechargeTime(new Date());
                                rechargeGiveLog.setGiveMoney(rechargeGive.getGiveMoney());
                                rechargeGiveLog.setUserName(user.getName());
                                rechargeGiveLog.setUserPhone(user.getPhone());
                                rechargeGiveLog.setBaseMoney(rechargeGive.getBaseMoney());
                                /**添加赠送金额变动*/
                                GiftCardUser giftCardUser = new GiftCardUser();
                                //GiftCardUser giftCardUserDB = giftCardUserService.getByUserId(user.getUserId(),agentId);
                                /** 添加金额变动日志 */
                                if (rechargeGive.getGiveMoney() > 0) {
                                    giftCardUser.setMoney(rechargeGive.getGiveMoney());
                                    giftCardUser.setUserId(user.getUserId());
                                    giftCardUser.setAccountId(agentId);
                                    giftCardUserService.insert(giftCardUser, "充值赠送礼品卡", BusinessConstant.BUSINESS_RECHARGE_GIF_GIVE, recharge.getOrderNO(), dateTime);
                                }

                                /**添加赠送优惠券*/
                                Coupon coupon = couponService.getByCouponId(rechargeGive.getCouponId());
                                if (coupon != null) {
                                    /**当优惠券失效日期大于当前日期，则新增用户绑定优惠券*/
                                    if (DateTimeUtil.getTimeDF(DateTimeUtil.getNowTime(), coupon.getEndTime()) > 0) {
                                        rechargeGiveLog.setCouponId(rechargeGive.getCouponId());
                                        rechargeGiveLog.setCouponCount(rechargeGive.getCouponCount());
                                        rechargeGiveLog.setValidDays(rechargeGive.getValidDays());
                                        List<CouponUser> userList = new LinkedList<>();
                                        for (Integer i = 0; i < rechargeGive.getCouponCount(); i++) {
                                            CouponUser couponUser = new CouponUser();
                                            couponUser.setAccountId(agentId);
                                            couponUser.setUserId(user.getUserId());
                                            couponUser.setCouponId(coupon.getCouponId());
                                            couponUser.setIsUse(0);
                                            couponUser.setRecTime(dateTime);
                                            couponUser.setIsValid(1);
                                            /**若设置了多少天过期，则失效时间为当前时间往后多少天*/
                                            if (rechargeGive.getValidDays() != null) {
                                                couponUser.setExpireTime(DateTimeUtil
                                                        .DateTimeToString(DateTimeUtil.addDay(new Date(), rechargeGive.getValidDays())));
                                            } else {
                                                couponUser.setExpireTime(coupon.getEndTime());
                                            }
                                            userList.add(couponUser);
                                        }
                                        /**批量添加*/
                                        if (userList.size() > 0) {
                                            couponUserService.addBatch(userList);
                                        }
                                    }
                                }
                                /**记录充值赠送日志*/
                                rechargeGiveLogDao.insert(rechargeGiveLog);
                                break;
                            }
                        }
                    }
                    redisService.del(user.getUserId() + ".agentId");
                }

                /**更新账户金额和时间(旧金额+充值金额)*/
                userService.updateMoney(user.getUserId(), recharge.getMoney());

                Double updateMoney = recharge.getMoney();

                /**添加金额变动日志*/
                addUserAccountLog(user, dateTime, recharge.getMoney(), RechargeConstant.MONEY_TYPE_REAL, RechargeConstant.RECHARGE_TYPE_RECHARGE, "充值");

                String msg = "订单编号:" + recharge.getOrderNO() + ";充值金额:" + recharge.getMoney() / 100 + "元";
                log.info(msg);
                log.info("用户信息-1:{}", user);
                Double userRealMoney = user.getMoney() - user.getRideMoney();
                //如果用户金额之前是负的，并且充值后的钱为正的，更新用户最后一个骑行订单
                if (userRealMoney < 0 && (userRealMoney + recharge.getMoney() >= 0)) {
                    boolean balanceLogPush = true;
                    User userDB = new User();
                    userDB.setUserId(user.getUserId());
                    userDB.setRideMoney(0);
                    userDB.setMoney(user.getMoney() + recharge.getMoney() - user.getRideMoney());
                    userDB.setUpdateTime(dateTime);
                    userService.updateRideMoney(userDB);
                    log.info("用户信息变更信息:{}", userDB);
                    /**实际更新用户余额*/
                    updateMoney = user.getMoney() + recharge.getMoney() - user.getRideMoney();

                    log.info("微信更新用户[" + user.getPhone() + "]最后一笔骑行日志中的支付时间");
                    try {
                        //先查询
                        RideLog rideLog = rideLogService.findLastByUserId(user.getUserId());
                        /**最近一单骑行已支付，找有无未支付订单*/
                        if (rideLog == null || rideLog.getPayTime() != null) {
                            rideLog = rideLogService.findNOtPayByUserId(user.getUserId());
                        }
                        RideLogDetails rideLogDetails;
                        String concatRemark = "";
                        if (rideLog != null && rideLog.getPayTime() == null) {
                            Date payTime = DateTimeUtil.StringToDateTime(dateTime);
                            rideLogService.updatePayTimeByUserIdAndOrderNO(user.getUserId(), payTime, rideLog.getOrderNO());
                            dispatchLogDao.update(rideLog.getOrderNO(), dateTime, rideLog.getMoney().longValue());
                            rideLogDetails = new RideLogDetails();
                            rideLogDetails.setOrderId(rideLog.getOrderNO());
                            rideLogDetails.setPayTime(payTime);
                            rideLogDetails.setPayStatus(RideLogDetailsConstant.ORDER_PAY);
                            rideLogDetails.setOrderType(RideLogDetailsConstant.ORDER_TYPE_REPAYMENT_OF_ARREARS);
                            rideLogDetails.setActualPayMoney(rideLog.getMoney().longValue());
                            rideLogDetails.setMerchantNO(recharge.getOrderNO());
                            rideLogDetailsDao.edit(rideLogDetails);

                            // 插入用户操作日志
                            userOpLogService.insertSingle(UserOpLog.builder()
                                    .accountId(user.getAccountId())
                                    .operation("订单支付")
                                    .opUser(user.getName())
                                    .opUserPhone(user.getPhone())
                                    .targetUser(user.getName())
                                    .targetUserPhone(user.getPhone())
                                    .opPlatform(OperationPlatform.CLIENT.code)
                                    .opTime(LocalDateTime.now())
                                    .result(true)
                                    .detail("支付方式: " + getPayTypeName(recharge.getType()) + "\n骑行订单号: " + rideLog.getOrderNO() + "\n变动金额: " + rideLog.getMoney() / 100 + "元")
                                    .build());

                            //充值用于超时结束订单金额也需要分账

                            if (Objects.equals(delayPayQKBJSwitch.getModel(),DelayPayQKBJSwitch.REAL_TIME)){
                                if (user.getMoney() > 0){
                                    delay(user.getMoney(), rideLog.getAccountId(), user, rideLog.getOrderNO(), rideLog.getMoney().intValue());
                                }
                            }else {
                                delay(rideLog.getMoney(), rideLog.getAccountId(), user, rideLog.getOrderNO(), rideLog.getMoney().intValue());
                            }

//                            delay(rideLog.getMoney(), rideLog.getAccountId(), user, rideLog.getOrderNO(), rideLog.getMoney().intValue());

                            //欠款补交也要记录订单收费详情
                            RechargeMerchant rechargeMerchant = rechargeMerchantService.getByOrderNO(recharge.getOrderNO());
                            rideUseLogService.insert(rideLog.getOrderNO(), rideLog.getAccountId(), user.getAccountId(),
                                    rideLog.getMoney().intValue(), user.getMoney().intValue(), RechargeConstant.recharge_QKBJ,
                                    payTime, rechargeMerchant);
                        } else {
                            log.info("[{} - 无订单欠款补交金额{}]", user.getPhone(), recharge.getMoney());
                            rideLogDetails = new RideLogDetails();
                            rideLog = new RideLog();
                            rideLog.setAccountId(-1);
                            rideLog.setOrderNO("");
                            concatRemark = "-无订单";
                            BadOrder badOrder = new BadOrder(user.getAccountId(), -1, recharge.getMoney().longValue(), 1,
                                    new Date(), null, "", "", new Date(), "无订单欠款补交");
                            badOrderDao.insert(badOrder);
                            recharge.setAdAccountId(-1);
                        }
                        //欠款补交
                        Account account = Optional.ofNullable(accountService.getByAccountId(rideLog.getAccountId())).orElse(new Account());
                        //欠款推送日志
                        addArrearsLog(user, rideLog, dateTime, account.getName(), recharge.getOrderNO(), rideLogDetails,
                                ArrearsLogContent.MAKE_UP_THE_RECHARGE, "充值补交扣费" + concatRemark,
                                (int) user.getRideMoney(), recharge.getMoney().intValue(), (int) (user.getRideMoney() - recharge.getMoney().intValue()));
                        //欠款补交添加扣费记录
                        if (user.getMoney() > 0) {
                            addArrearsLog(user, rideLog, dateTime, account.getName(), null, rideLogDetails,
                                    ArrearsLogContent.MAKE_UP_THE_BALANCE, "余额补交扣费" + concatRemark,
                                    user.getMoney().intValue(), user.getMoney().intValue(), 0);
                            machineService.addBalanceChange(user, rideLog.getOrderNO(), rideLog.getAccountId(), DateTimeUtil.StringToDateTime(dateTime).getTime(), BalanceLogChangeTypeContent.capitalType_balance
                                    , BusinessConstant.BUSINESS_BALANCE_OF_CYCLING, user.getMoney().longValue(), user.getMoney().longValue()
                                    , "余额补交扣费" + concatRemark, PayPlatformContent.PAY_USE);
                        }
                        userAccountMoneyService.editRideMoney(user.getAccountId(), rideLog.getAccountId(), DateTimeUtil.StringToDateTime(dateTime).getTime(), user.getUserId());
                        log.info("用户信息-3:{}", userDB);
                    } catch (Exception e) {
                        log.error("微信更新rideLog错误" + e.getMessage(), e);
                    }
                    changeStartMoney = 0L;
                    changeEndMoney = 0L;
                    transactionType = TransationLogConstant.BUSINESS_REPAYMENT_OF_ARREARS;
                    capitalType = PayPlatformContent.PAY_RIDELOG_PAY;
                    businessType = BusinessConstant.BUSINESS_REPAYMENT_OF_ARREARS;
                    changeType = PayPlatformContent.PAY_RECHARGE;
                    remark = "欠款补交";
                    addBalanceChange(user, recharge, dateTime, capitalType, businessType
                            , changeStartMoney, recharge.getMoney().longValue(), changeEndMoney, remark, changeType);
                } else {
                    machineService.addBalanceChange(user, recharge.getOrderNO(), recharge.getAdAccountId(), DateTimeUtil.StringToDateTime(dateTime)
                                    .getTime(), capitalType, businessType
                            , changeStartMoney, recharge.getMoney().longValue(), "充值", PayPlatformContent.PAY_RECHARGE);
                    addBalanceChange(user, recharge, dateTime, capitalType, businessType
                            , changeStartMoney, recharge.getMoney().longValue(), changeEndMoney, "充值", changeType);
                }
                /**更新用户余额归属*/
                updateAdaPayMoney(recharge, user, updateMoney);
            }


        } else if (recharge.getRechargeType().equals(RechargeConstant.recharge_returnBike)) {
            // 添加事件埋点
            EventPutDTO eventPutDTO = new EventPutDTO();
            eventPutDTO.setEventTime(DateUtil.toLocalDateTime(new Date()));
            eventPutDTO.setEventType("paySuccess");
            eventPutDTO.setEventDesc("支付成功");
            eventPutDTO.setUri("callback");
            eventPutDTO.setUserId(user.getUserId());
            eventPutDTO.setOrderNo(recharge.getOrderNO());
            eventPutDTO.setPutType("server_put");
            eventPutDTO.setUserPhone(user.getPhone());
            eventPutDTO.setBrandId(recharge.getBrandId());
            eventPutDTO.setAccountId(recharge.getAdAccountId());
            eventHandleService.handle(eventPutDTO);

            capitalType = PayPlatformContent.PAY_RIDELOG_PAY;
            businessType = BusinessConstant.BUSINESS_BALANCE_CYCLING;
            remark = "充值结束订单";
            changeStartMoney = 0L;
            changeEndMoney = 0L;
            transactionType = TransationLogConstant.BUSINESS_BALANCE_CYCLING;
            //充值结束订单
            LogUtil.info("[" + user.getPhone() + "]充值到账自动结束订单");

            /**更新账户金额和时间(旧金额+充值金额)*/
            userService.updateMoney(user.getUserId(), recharge.getMoney());

            /**添加金额变动日志*/
            addUserAccountLog(user, dateTime, recharge.getMoney(), RechargeConstant.MONEY_TYPE_REAL, RechargeConstant.RECHARGE_TYPE_RECHARGE, "订单充值");

            String msg = "[微信充值结束订单]订单编号:" + recharge.getOrderNO() + ";充值金额:" + recharge.getMoney() / 100 + "元";
            log.info(msg);

            /**是否是调度还车*/
            Integer dispatchType = null;
            String dispatchTypeString = redisService.get(RedisConstant.REDIS_ACCOUNT_USER_DISPATCH + user.getUserId());
            if (dispatchTypeString != null) {
                dispatchType = Integer.parseInt(dispatchTypeString);
                LogUtil.info("调度还车[" + dispatchType + "]");
            }
            /**调用结束订单*/
            /**生成流水号*/
            try {
                String serNO = UUID.randomUUID().toString();
                RidePayLog ridePayLog = ridePayLogService.getByPayOrderNO(recharge.getOrderNO());
                if (ridePayLog != null) {
                    Machine machine = machineBorrowDao.getRideByUserId(user.getUserId());
                    String brtInfo = ridePayLog.getRideRemark();
                    BorrowReturnTer info = JSONObject.parseObject(brtInfo, BorrowReturnTer.class);
                    info.setMerchantNO(recharge.getOrderNO());
                    info.setPayTime(dateTime);
                    info.setPayMoney(recharge.getMoney());
                    machineService.handlePay(info);

                    // 插入用户操作日志
                    userOpLogService.insertSingle(UserOpLog.builder()
                            .accountId(info.getAccountId())
                            .operation("订单支付")
                            .opUser(user.getName())
                            .opUserPhone(user.getPhone())
                            .targetUser(user.getName())
                            .targetUserPhone(user.getPhone())
                            .opPlatform(OperationPlatform.CLIENT.code)
                            .opTime(LocalDateTime.now())
                            .result(true)
                            .detail("支付方式: " + getPayTypeName(recharge.getType()) + "\n骑行订单号: " + ridePayLog.getRideOrderNO() + "\n变动金额: " + recharge.getMoney() / 100 + "元")
                            .build());

                    /**给终端下发指令*/
                    redisService.add(RedisConstant.REDIS_TER_PAY_FINISHORDER_SERNO + serNO, serNO, 60);
                    terControlService.sendControl(serNO, machine.getMachineNO(), ControlTypeConstant.CONTROL_TYPE_CONTROL, ControlTypeConstant.CONTROL_TYPE_LOCK, "", machine, false, -1, user.getUserId(), "充值结束订单指令下发[GPRS]");
                    addRideFeelog(ridePayLog.getRideOrderNO(), machine.getAccountId(), user
                            , (int) (user.getMoney() + recharge.getMoney()), recharge, RechargeConstant.recharge_returnBike);

                    // 插入用户操作日志
                    machineOpLogService.insertSingle(MachineOpLog.builder()
                            .accountId(user.getAccountId())
                            .machineId(machine.getMachineId())
                            .machineNO(machine.getMachineNO())
                            .userCode(machine.getUserCode())
                            .opUser(user.getName())
                            .opUserPhone(user.getPhone())
                            .operation("关锁还车")
                            .opType("用户还车")
                            .opPlatform(OperationPlatform.CLIENT.code)
                            .opTime(LocalDateTime.now())
                            .result(true)
                            .detail("指令流水号: " + serNO + "\n骑行单号: " + ridePayLog.getRideOrderNO())
                            .build());

                    /**充值结束订单时，用户金额大于0，也需要分账*/
                    if (user.getMoney() > 0) {
                        delay(user.getMoney(), machine.getAccountId(), user, ridePayLog.getRideOrderNO(),(int) (user.getMoney() + recharge.getMoney()));
                    }
                } else {
                    remark = "充值结束订单转充值";
                    capitalType = PayPlatformContent.PAY_BALANCE;
                    businessType = BusinessConstant.BUSINESS_USER_RECHARGE_BALANCE;
                    transactionType = TransationLogConstant.BUSINESS_USER_RECHARGE_BALANCE;
                    /**无数据,更改订单类型为普通充值*/
                    recharge.setRechargeType(RechargeConstant.recharge_pay);
                    rechargeService.editType(recharge);
                    changeStartMoney = user.getMoney().longValue();
                    changeEndMoney = user.getMoney().longValue() + recharge.getMoney().longValue();
                    /**控制修改区域余额*/
                    machineService.addBalanceChange(user, recharge.getOrderNO(), recharge.getAdAccountId(), DateTimeUtil.StringToDateTime(dateTime)
                                    .getTime(), capitalType, businessType
                            , changeStartMoney, recharge.getMoney().longValue(), "充值结束订单转充值", PayPlatformContent.PAY_RECHARGE);
                    /**日志推送*/
                    addBalanceChange(user, recharge, dateTime, capitalType, businessType
                            , changeStartMoney, recharge.getMoney().longValue(), changeEndMoney, "充值结束订单转充值", changeType);
                }
                //}
            } catch (Exception e) {
                LogUtil.warn(user.getUserId() + "充值到账结束订单失败");
                log.error("充值到账结束订单失败", e);
            }
        } else if (recharge.getRechargeType().equals(RechargeConstant.recharge_vip)) {
            capitalType = PayPlatformContent.PAY_CARD;
            businessType = BusinessConstant.BUSINESS_BUY_VIP;
            remark = "会员卡购买";
            changeStartMoney = 0L;
            changeEndMoney = 0L;
            transactionType = TransationLogConstant.BUSINESS_BUY_VIP;
            //会员卡订单
            VipCardLog vipCardLog = vipCardLogService.getByOrderNO(recharge.getOrderNO());
            if (vipCardLog != null) {
                VipCard vipCard = vipCardService.getById(vipCardLog.getVipId());
                if (vipCard != null) {
                    /**免押开启*/
                    if (vipCard.getFreeDeposit() == 1) {
                        /**默认失效时间为会员卡购买时间*/
                        String endDate = vipCardLog.getExpireDate();
                        /**用户已购买，则时间累加*/
                        AgentDepositVip agentDepositVip = agentDepositVipService.getByUserId(user.getUserId(), vipCardLog.getAccountId());
                        if (agentDepositVip != null) {
                            endDate = DateTimeUtil.getServiceEndDate(agentDepositVip.getExpireDt(), vipCard.getType());
                        } else {
                            agentDepositVip = new AgentDepositVip();
                        }
                        agentDepositVip.setAccountId(vipCard.getAccountId());
                        agentDepositVip.setExpireDt(endDate);
                        agentDepositVip.setUserId(user.getUserId());
                        agentDepositVipService.insert(agentDepositVip);
                    }
                } else {
                    log.info("会员卡已被删除,订单号=" + recharge.getOrderNO());
                }
                /**修改已支付*/
                VipCardLog vipCardLogDB = new VipCardLog();
                vipCardLogDB.setOrderNO(recharge.getOrderNO());
                vipCardLogDB.setPayTime(DateTimeUtil.StringToDateTime(dateTime));
                vipCardLogService.editPay(vipCardLogDB);
                /** 资金变更记录 */
                addUserAccountLog(user, dateTime, recharge.getMoney(), RechargeConstant.MONEY_TYPE_REAL, RechargeConstant.RECHARGE_TYPE_CONSUMPTION, "会员卡开通费用");

                Account account = accountService.getByAccountId(vipCardLog.getAccountId());
                /**日志数据异步入库*/
                PayCardLog payCardLog = new PayCardLog(user.getUserId(), user.getPhone(), user.getName(), vipCardLog.getAccountId()
                        , user.getAccountId(), account.getName(), recharge.getOrderNO(),
                        BusinessConstant.BUSINESS_BUY_VIP, vipCard.getName(),
                        PayCardLogContent.vip_card, vipCard.getType(), tranbusinessType(recharge.getType()), recharge.getMoney().longValue(), DateTimeUtil.StringToDateTime(dateTime)
                        , "会员卡充值");
                pushMsgLogService.sendPushLog(JSON.toJSONString(payCardLog), TableNameConstant.PAYCARDLOG);
                // 插入用户操作日志
                userOpLogService.insertSingle(UserOpLog.builder()
                        .accountId(user.getAccountId())
                        .opUser(user.getName())
                        .opUserPhone(user.getPhone())
                        .targetUser(user.getName())
                        .targetUserPhone(user.getPhone())
                        .operation("会员卡变动")
                        .opType("用户购买")
                        .opPlatform(OperationPlatform.CLIENT.code)
                        .opTime(LocalDateTime.now())
                        .result(true)
                        .detail("会员卡名称: " + vipCard.getName() + "\n会员卡ID: " + vipCardLog.getVipId())
                        .build());
            } else {
                log.info("会员卡订单号不存在" + recharge.getOrderNO());
            }
            addRideFeelog(recharge.getOrderNO(), vipCardLog.getAccountId(), user
                    , recharge.getMoney().intValue(), recharge, RechargeConstant.recharge_vip);
        } else if (recharge.getRechargeType().equals(RechargeConstant.recharge_meal)) {
            /**用户购买优惠券套餐*/
            /**查询用户购买订单*/
            capitalType = PayPlatformContent.PAY_CARD;
            businessType = BusinessConstant.BUSINESS_BUY_MEAL;
            remark = "优惠券套餐购买";
            changeStartMoney = 0L;
            changeEndMoney = 0L;
            transactionType = TransationLogConstant.BUSINESS_BUY_MEAL;
            UserMealLog userMealLog = userMealLogDao.getByOrderNO(recharge.getOrderNO());
            if (userMealLog == null) {
                return;
            }
            Integer mealId = Integer.valueOf(userMealLog.getMealId());
            CouponMeal couponMeal = couponMealService.getByMealId(mealId);
            if (couponMeal == null) {
                log.warn("优惠活动不存在" + mealId);
                return;
            }
            userMealLog.setState(1);
            userMealLogDao.edit(userMealLog);

            /**触发优惠券绑定*/
            List<CouponUser> list = new ArrayList<>();
            for (int i = 0; i < couponMeal.getCouponNum(); i++) {
                CouponUser couponUser = new CouponUser();
                couponUser.setAccountId(couponMeal.getAccountId());
                couponUser.setUserId(user.getUserId());
                couponUser.setCouponId(couponMeal.getCouponId());
                couponUser.setRecTime(dateTime);
                couponUser.setIsUse(0);
                couponUser.setIsValid(1);
                couponUser.setOrderNO(recharge.getOrderNO());
                couponUser.setExpireTime(
                        DateTimeUtil.DateTimeToString(DateTimeUtil.addDay(new Date(), couponMeal.getValidDays())));
                list.add(couponUser);
            }
            if (list.size() > 0) {
                couponUserService.addBatch(list);
            }
            /** 资金变更记录 */
            addUserAccountLog(user, dateTime, recharge.getMoney(), RechargeConstant.MONEY_TYPE_REAL, RechargeConstant.RECHARGE_TYPE_CONSUMPTION, "优惠券套餐购买费用");

            Account account = accountService.getByAccountId(couponMeal.getAccountId());
            /**日志数据异步入库*/
            PayCardLog payCardLog = new PayCardLog(user.getUserId(), user.getPhone(), user.getName(), couponMeal.getAccountId()
                    , user.getAccountId(), account.getName(), recharge.getOrderNO(),
                    BusinessConstant.BUSINESS_BUY_MEAL, couponMeal.getName(),
                    PayCardLogContent.coupon_card, null,
                    tranbusinessType(recharge.getType()), recharge.getMoney().longValue(), DateTimeUtil.StringToDateTime(dateTime)
                    , "优惠券套餐充值");
            pushMsgLogService.sendPushLog(JSON.toJSONString(payCardLog), TableNameConstant.PAYCARDLOG);
            addRideFeelog(recharge.getOrderNO(), couponMeal.getAccountId(), user
                    , recharge.getMoney().intValue(), recharge, RechargeConstant.recharge_meal);

            // 插入用户操作日志
            userOpLogService.insertSingle(UserOpLog.builder()
                    .accountId(user.getAccountId())
                    .opUser(user.getName())
                    .opUserPhone(user.getPhone())
                    .targetUser(user.getName())
                    .targetUserPhone(user.getPhone())
                    .operation("优惠套餐")
                    .opType("用户购买")
                    .opPlatform(OperationPlatform.CLIENT.code)
                    .opTime(LocalDateTime.now())
                    .result(true)
                    .detail("优惠套餐名称: " + couponMeal.getName() + "\n优惠套餐ID: " + couponMeal.getCouponId())
                    .build());
        } else {
            return;
        }
        addTransationLog(user, recharge, recharge.getOrderNO(), dateTime, tranbusinessType(recharge.getType()), transactionType,null);

        addUserCapitalChange(user, recharge, capitalType, businessType, dateTime, "", remark, firstId, changeStartMoney
                , recharge.getMoney().longValue(), changeEndMoney, changeType);

    }

    private static String getPayTypeName(Integer type) {
        if (RechargeConstant.WEIXIN_PAY_TYPE.contains(type)) {
            return "微信支付";
        } else if (RechargeConstant.ZFB_PAY_TYPE.contains(type)) {
            return "支付宝支付";
        } else {
            return "其他渠道(" + type + ")";
        }
    }

    private boolean hasRecentChargeReturnBike(Integer userId) {
        /**充值到账结束订单限制*/
        String key = RedisConstant.RECHARGE_RETURNBIKE_PAYMENT_FINISH + userId;
        String orderNO = redisService.get(key);
        if (orderNO != null) {
           return true;
        }
        return false;
    }

    private WeixinPayConfig checkWxPayPlus(Integer accountId, Integer type, String code, Integer adAccountId) {
        /**支付配置信息(1:微信APP支付；2：微信小程序支付) 先查询区域的配置，在查询品牌的配置*/
        WeixinPayConfig weixinPayConfig = weixinPayConfigService.getByAccountId(adAccountId, type);
        if (weixinPayConfig == null) {
            weixinPayConfig = weixinPayConfigService.getByAccountId(accountId, type);
        }
        if (weixinPayConfig == null) {
            throw new BaseException("-2006", "该品牌微信支付未配置");
        }
        /**获取微信openId*/
        String openId = MyX509TrustManager.getOpenId(code, weixinPayConfig);
        if (openId == null) {
            throw new BaseException("-3026", "获取微信openId失败");
        }
        weixinPayConfig.setOpenId(openId);
        return weixinPayConfig;
    }

    /**
     * 添加补交记录
     *
     * @param user
     * @param rideLog
     * @param dateTime
     * @param accountName
     * @param orderNO
     * @param rideLogDetails
     * @param makeUpType
     */
    public void addArrearsLog(User user, RideLog rideLog, String dateTime,
                              String accountName, String orderNO, RideLogDetails rideLogDetails, Integer makeUpType
            , String remark, Integer startMoney, Integer changeMoney, Integer endMoney) {

        ArrearsLog arrearsLog = new ArrearsLog(user.getUserId(), user.getPhone(), user.getName(), rideLog.getAccountId(), user.getAccountId()
                , accountName, rideLog.getOrderNO(), ArrearsLogContent.PAY, makeUpType
                , changeMoney, startMoney, endMoney, DateTimeUtil.StringToDateTime(dateTime).getTime(), orderNO, rideLogDetails.getOperatorId()
                , rideLogDetails.getOperatorName(), "", remark);
        log.info("用户信息-2 欠款日志:{}", arrearsLog);
        pushMsgLogService.sendPushLog(JSON.toJSONString(arrearsLog), TableNameConstant.ARREARSLOG);
    }

    /**
     * @param user
     * @param recharge
     * @param dateTime
     * @param capitalType
     * @param businessType
     */
    @Override
    public void addBalanceChange(User user, Recharge recharge, String dateTime, Integer capitalType, Integer businessType
            , Long startMoney, Long changeMoney, Long changeEndMoney, String remark, Integer type) {
        BalanceChange balanceChange = new BalanceChange(user.getUserId(), user.getPhone(), user.getName(), recharge.getAdAccountId()
                , user.getAccountId(), startMoney, changeMoney
                , changeEndMoney, type
                , capitalType, businessType
                , DateTimeUtil.StringToDateTime(dateTime).getTime(), remark, recharge.getOrderNO());
        pushMsgLogService.sendPushLog(JSON.toJSONString(balanceChange), TableNameConstant.BALANCECHANGE);
		/*userAccountMoneyService.editMoney(user,recharge.getOrderNO(),changeMoney,capitalType,recharge.getAdAccountId()
				,type,DateTimeUtil.StringToDateTime(dateTime).getTime(),remark);*/
    }

    /**
     * 用户资金变动日志入库（旧表）
     *
     * @param user
     * @param dateTime
     * @param money
     * @param moneyType
     * @param type
     * @param remark
     */
    public void addUserAccountLog(User user, String dateTime, Double money, Integer moneyType, Integer type, String remark) {
        UserAccountLog userAccountLog = new UserAccountLog();
        userAccountLog.setAccountId(user.getAccountId());
        userAccountLog.setUserId(user.getUserId());
        userAccountLog.setOperaTime(dateTime);
        userAccountLog.setMoney(money);
        userAccountLog.setMoneyType(moneyType);
        userAccountLog.setType(type);
        userAccountLog.setRemark(remark);
        userAccountLogService.insert(userAccountLog);
    }

    /**
     * 添加新用户资金变动日志
     *
     * @param user         用户信息
     * @param recharge     充值记录
     * @param capitalType  资金类型1
     * @param businessType 业务类型
     * @param dateTime     发生时间
     * @param details      详情
     * @param remark       备注
     */
    @Override
    public void addUserCapitalChange(User user, Recharge recharge, Integer capitalType, Integer businessType,
                                     String dateTime, String details, String remark, Integer originalAccountId, Long changeStartMoney, Long changeMoney, Long changeEndMoney
            , Integer type) {
        UserCapitalChange userCapitalChange = new UserCapitalChange(user.getUserId(), user.getPhone(), user.getName(), recharge.getAdAccountId(),
                user.getAccountId(), changeStartMoney, changeMoney, changeEndMoney, type, capitalType,
                businessType, details, null, null, null, recharge.getOrderNO(), recharge.getOrderNO(), DateTimeUtil.StringToDateTime(dateTime).getTime(),
                remark, originalAccountId);
        pushMsgLogService.sendPushLog(JSON.toJSONString(userCapitalChange), TableNameConstant.USERCAPITALCHANGE);
    }

    /**
     * 添加交易记录日志
     *
     * @param user        用户信息
     * @param recharge    充值订单信息
     * @param businessNO  业务订单号
     * @param dateTime    时间
     * @param payPlatform 平台类型
     */
    @Override
    public void addTransationLog(User user, Recharge recharge, String businessNO, String dateTime, Integer payPlatform, Integer transactionType,String remark) {
        Account account = accountService.getByAccountId(recharge.getAdAccountId());
        //Integer transactionType=tranTransationType(recharge.getRechargeType());
        TransationLog transationLog = new TransationLog(recharge.getOrderNO(), businessNO, user.getUserId(), user.getPhone(), user.getName()
                , recharge.getAdAccountId(), user.getAccountId(), account.getName(), recharge.getMoney().longValue(),
                IncomeTypeContent.inCome
                , DateTimeUtil.StringToDateTime(recharge.getRechargeTime()), DateTimeUtil.StringToDateTime(dateTime), new Date()
                , payPlatform, transactionType, 0L, DateTimeUtil.StringToDateTime(dateTime), null, null, null, null, null, 1, null);
        pushMsgLogService.sendPushLog(JSON.toJSONString(transationLog), TableNameConstant.TRANSACTIONLOG);
    }

    public void addRideFeelog(String orderNO, Integer accountId, User user, Integer money,
                              Recharge recharge, Integer type) {
        Integer realMoney = 0;
        if (recharge.getType().equals(RechargeConstant.RECHARGE_PAY_ADAPAY_ZFB) || recharge.getType().equals(
                RechargeConstant.RECHARGE_PAY_ADAPAY)) {
            realMoney = recharge.getMoney().intValue();
        }
        adaPayService.addRideFeeLog(orderNO, accountId, user, money, realMoney, type);
    }


    /**
     * 更新用户余额归属
     *
     * @param recharge
     * @param user
     * @param updateMoney
     */
    public void updateAdaPayMoney(Recharge recharge, User user, Double updateMoney) {
        /**确认是汇付充值，还是其他充值*/
        boolean isAdaPay = false;
        if (RechargeConstant.RECHARGE_PAY_ADAPAY.equals(recharge.getType()) || RechargeConstant.RECHARGE_PAY_ADAPAY_ZFB.equals(recharge.getType())) {
            isAdaPay = true;
        }
        /**更新用户余额归属*/
        if (isAdaPay) {
            userAdaPayMoneyService.add(user, 0, updateMoney.intValue());
        } else {
            userAdaPayMoneyService.add(user, updateMoney.intValue(), 0);
        }
    }

    @Override
    public Double getVipOrder_base(Integer type, User user, Integer vipId, String orderNO, Integer adAccountId) {
        Integer userId = user.getUserId();
        /**查询会员卡信息*/
        VipCard vipCard = vipCardService.getById(vipId);
        if (vipCard == null) {
            throw new BaseException("-150002", "会员卡不存在");
        }
        if (!vipCard.getAccountId().equals(adAccountId)) {
            throw new BaseException("-120008", "当前购买区域与套餐对应区域不一致，限制购买");
        }
        /**查询是否有购买会员卡*/
        VipLogDot vipLogDot = vipCardLogService.getVaild(adAccountId, userId, vipCard.getFeeId());
        if (vipLogDot != null) {
            throw new BaseException("-150003", "已存在生效中会员卡，请勿重复购买");
        }
        /**添加记录*/
        VipCardLog vipCardLog = new VipCardLog();
        vipCardLog.setVipId(vipId);
        vipCardLog.setAccountId(vipCard.getAccountId());
        vipCardLog.setMemberState(0);
        vipCardLog.setOrderNO(orderNO);
        vipCardLog.setUserId(userId);
        /**默认从当天开始计算*/
        String date = DateTimeUtil.getNowTimeYMD();
        vipCardLog.setExpireDate(DateTimeUtil.getServiceEndDate(date, vipCard.getType()));
        vipCardLog.setEffectDate(date);

        vipCardLogService.add(vipCardLog);

        /**订单表*/
        Recharge recharge = new Recharge();
        recharge.setRechargeType(RechargeConstant.recharge_vip);//0:押金;1:充值;2:免押会员;3:骑行会员;4折扣会员卡
        recharge.setType(type);//0:app;1:微信APP；2：微信小程序;3:支付宝
        recharge.setOrderNO(orderNO);
        recharge.setRechargeTime(DateTimeUtil.getNowTime());
        recharge.setUserId(userId);
        recharge.setState(0);
        recharge.setDeposit(false);
        recharge.setAdAccountId(vipCard.getAccountId());
        recharge.setBrandId(user.getAccountId());
        recharge.setMoney((double) vipCard.getMoney());
        recharge.setRemark("会员卡付费， " + "会员类型：" + vipCard.getType());
        recharge.setPhone(user.getPhone());
        rechargeService.insert(recharge);

        String wxMchPay = cacheService.getBrandRemoteConfigValue(user.getAccountId(), BrandConstant.WX_MCH_PAY_SWITCH);
        int rechargePayTyp = Objects.equals("1",wxMchPay) ? 1 : 0 ;
        rechargePayTypeDao.addOne(new RechargePayType(orderNO,rechargePayTyp,""));
        return ((double) vipCard.getMoney()) / 100;
    }

    @Override
    public String getMeal_weixin(String code, User user, Integer mealId, Integer adAccountId) {
        /**订单编号*/
        //String orderNO = "GXBIKEMEAL"+ DateTimeUtil.getDaformatyyyyMMddHHmmss(new Date()) + TenpayUtil.buildRandom(6);
        String orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_meal);
        /**聚合支付校验*/
        adaPayService.checkIsAdaPay(user.getAccountId());
        /**支付配置信息(1:微信APP支付；2：微信小程序支付)*/
		/*WeixinPayConfig weixinPayConfig=weixinPayConfigService.getByAccountId(user.getAccountId(),2);
		if(weixinPayConfig==null){
			throw new BaseException("-2006","该品牌微信支付未配置");
		}

		*//**获取微信openId*//*
		String openId=MyX509TrustManager.getOpenId(code,weixinPayConfig);
		if(openId==null){
			throw new BaseException("-3026","获取微信openId失败");
		}*/
        //WeixinPayConfig weixinPayConfig=checkWxPay(user.getAccountId(), RechargeConstant.RECHARGE_WEIXIN_XCX,code);
        WeixinPayConfig weixinPayConfig = checkWxPayPlus(user.getAccountId(), RechargeConstant.RECHARGE_WEIXIN_XCX, code, adAccountId);
        Double money = getMeal_base(RechargeConstant.RECHARGE_WEIXIN_XCX, user, mealId, orderNO, adAccountId);
        Account account = cacheService.getAccount(user.getAccountId());
        Account adAccount = cacheService.getAccount(adAccountId);
        /**生成订单信息提交微信*/
        WxPayDto tpWxPay = new WxPayDto();
        tpWxPay.setOpenId(weixinPayConfig.getOpenId());
        tpWxPay.setBody(account.getName() + "-" + adAccount.getName() + "-" + GoodsConstant.GOODS_NAME_MEAL);
        tpWxPay.setOrderId(orderNO);
        tpWxPay.setSpbillCreateIp("127.0.0.1");
        tpWxPay.setTotalFee(String.valueOf(money));
        String wxMchPay = cacheService.getBrandRemoteConfigValue(user.getAccountId(), BrandConstant.WX_MCH_PAY_SWITCH);
        String result = WeixinPay.getPackage(weixinPayConfig, tpWxPay, Objects.equals(wxMchPay,"1"));
        String payApiType = Objects.equals("1",wxMchPay) ? PayApiTypeEnum.WECHAT_MCH_V3.getApiType() : PayApiTypeEnum.WECHAT_V2.getApiType();
        /**支付信息推送mq队列*/
        sendPayMsg(orderNO, RechargeConstant.PAY_CREATE, payApiType);
        return result;
    }

    @Override
    public WeixinPayParam getMeal_app(User user, Integer mealId, Integer adAccountId) {
        /**订单编号*/
        String orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_meal);
        /**聚合支付校验*/
        adaPayService.checkIsAdaPay(user.getAccountId());
        /**支付配置信息(1:微信APP支付；2：微信小程序支付)*/
        WeixinPayConfig weixinPayConfig = weixinPayConfigService.getByAccountId(user.getAccountId(),
                RechargeConstant.RECHARGE_WEIXIN_APP);
        if (weixinPayConfig == null) {
            throw new BaseException("-2006", "该品牌微信支付未配置");
        }
        //0:app;1:微信APP；2：微信小程序;3:支付宝
        Double money = getMeal_base(RechargeConstant.RECHARGE_WEIXIN_APP, user, mealId, orderNO, adAccountId);
        Account account = cacheService.getAccount(user.getAccountId());
        Account adAccount = cacheService.getAccount(adAccountId);
        /**生成订单信息提交微信*/
        WxPayDto tpWxPay = new WxPayDto();
        tpWxPay.setBody(account.getName() + "-" + adAccount.getName() + "-" + GoodsConstant.GOODS_NAME_MEAL);
        tpWxPay.setOrderId(orderNO);
        tpWxPay.setSpbillCreateIp("127.0.0.1");
        tpWxPay.setTotalFee(String.valueOf(money));

        WeixinPayParam wpp = WeixinPay.getPackage_app(weixinPayConfig, tpWxPay);
        /**支付信息推送mq队列*/
        sendPayMsg(orderNO, RechargeConstant.PAY_CREATE,null);
        return wpp;
    }

    @Override
    public Double getMeal_base(Integer type, User user, Integer mealId, String orderNO,
                               Integer adAccountId) {
        Integer userId = user.getUserId();
        CouponMeal couponMeal = couponMealService.getByMealId(mealId);
        if (couponMeal == null) {
            throw new BaseException("-150004", "该优惠套餐不存在");
        }
        if (!couponMeal.getAccountId().equals(adAccountId)) {
            throw new BaseException("-120008", "当前购买区域与套餐对应区域不一致，限制购买");
        }
        /**记录日志*/
        UserMealLog userMealLog = new UserMealLog();
        userMealLog.setAccountId(couponMeal.getAccountId());
        userMealLog.setAddTime(new Date());
        userMealLog.setOrderNO(orderNO);
        userMealLog.setState(0);
        userMealLog.setMealId(mealId);
        userMealLog.setPrice(couponMeal.getRealPrice());
        userMealLog.setUserId(user.getUserId());
        userMealLog.setRemark("优惠券套餐");
        userMealLogDao.add(userMealLog);

        /**订单表*/
        Recharge recharge = new Recharge();
        recharge.setRechargeType(RechargeConstant.recharge_meal);
        recharge.setType(type);
        recharge.setOrderNO(orderNO);
        recharge.setRechargeTime(DateTimeUtil.getNowTime());
        recharge.setUserId(userId);
        recharge.setState(0);
        recharge.setBrandId(user.getAccountId());
        recharge.setAdAccountId(couponMeal.getAccountId());
        recharge.setDeposit(false);
        recharge.setMoney((double) couponMeal.getRealPrice());
        recharge.setRemark("优惠券套餐购买");
        recharge.setPhone(user.getPhone());
        rechargeService.insert(recharge);

        String wxMchPay = cacheService.getBrandRemoteConfigValue(user.getAccountId(), BrandConstant.WX_MCH_PAY_SWITCH);
        int rechargePayTyp = Objects.equals("1",wxMchPay) ? 1 : 0 ;
        rechargePayTypeDao.addOne(new RechargePayType(orderNO,rechargePayTyp,""));
        /**缓存五分钟*/
        redisService.add(RedisConstant.USER_MEAL + userId, String.valueOf(mealId), 300);
        return ((double) couponMeal.getRealPrice()) / 100;
    }

    @Override
    public String getAccessToken(WeixinPayConfig weixinPayConfig) {
        String weixinAccessToken = redisService.get("AccessToken" + weixinPayConfig.getAccountId());
        /*判断时效性(2个小时获取一次)*/
        if (weixinAccessToken != null) {
            return weixinAccessToken;
        }
        weixinAccessToken = WxzffModelMsgUtil
                .getAccessToken(weixinPayConfig.getAccountId(), weixinPayConfig.getAppId(), weixinPayConfig.getSecret());
        /**放入redis*/
        redisService.add("AccessToken" + weixinPayConfig.getAccountId(), weixinAccessToken, 60 * 60);
        return weixinAccessToken;
    }

    @Override
    public void checkIsByMem(User user, Integer adAccountId) {
        User userDB = userService.getByUserId(user.getUserId());
        AdAccountDeposit adAccountDeposit = adAccountDepositService.getByAccountId(adAccountId);
        if (adAccountDeposit != null && ((userDB.getDepositState() == DepositStateConstant.DEPOSIT_STATE_PAY
                && userDB.getDepositMoney() >= adAccountDeposit.getDeposit()) || userDB.getDepositState() == DepositStateConstant.DEPOSIT_STATE_SCORE
                || userDB.getDepositState() == DepositStateConstant.DEPOSIT_STATE_ZMXY)) {
            throw new BaseException("-3009", "已交押金");
        }
    }

    @Override
    public WeixinPayConfig checkWxPay(Integer accountId, Integer type, String code) {
        /**支付配置信息(1:微信APP支付；2：微信小程序支付)*/
        WeixinPayConfig weixinPayConfig = weixinPayConfigService.getByAccountId(accountId, type);
        if (weixinPayConfig == null) {
            throw new BaseException("-2006", "该品牌微信支付未配置");
        }

        /**获取微信openId*/
        String openId = MyX509TrustManager.getOpenId(code, weixinPayConfig);
        if (openId == null) {
            throw new BaseException("-3026", "获取微信openId失败");
        }
        weixinPayConfig.setOpenId(openId);
        return weixinPayConfig;
    }

    @Override
    public void sendLockMsg(Integer accountId, Integer userId, Map<String, String> map, Integer type, Integer cardType) {
        WeixinPushModel weixinPushModel = weixinPushModelService.getByAccountId(accountId, type);
        if (weixinPushModel == null) {
            return;
        }
        WeixinPayConfig weixinPayConfig = getWeixinPayConfig(accountId);
        String accessToken = getAccessToken(weixinPayConfig);
        /**构造数据*/
        UserWxzff userWxzff = getUserWxzff(userId);
        String page = weixinPushModel.getPage();
        if (cardType != null) {
            page = page + cardType;
        }
        WeiXinModelData weiXinModelData = new WeiXinModelData(accessToken, userWxzff.getOpenId(), weixinPushModel.getTemplateId(), page, map);
        MqData mqData = new MqData();
        mqData.setMsgId(GatewayProtocol.MQ_MSG_ID_HTTP_MODEL_PUSH);
        mqData.setFeedback(RabbitMQData.modelqueue);
        mqData.setData(weiXinModelData);
        terControlService.sendPushMsg(RabbitMQData.modelqueue, JSON.toJSONString(mqData));
        log.info(String.format("用户id:%s发送服务推送消息,%s", userId, JSON.toJSONString(mqData)));
    }

    @Override
    public String getUrlScheme(Integer accountId, Integer type) {
        WeixinPayConfig weixinPayConfig = getWeixinPayConfig(accountId);
        String accessToken = getAccessToken(weixinPayConfig);
        BrandRemoteConfig brandRemoteConfig = cacheService.getBrandRemoteConfig(accountId, type);
        if (brandRemoteConfig == null) {
            return null;
        }
        String page = brandRemoteConfig.getParamKV().substring(brandRemoteConfig.getParamKV().indexOf("=") + 1);
        String data = WxUtils.getUrlScheme(accessToken, page, DateUtil.tomorrow().getTime());
        return data;
    }

    @Override
    public void sendPayMsg(String orderNO, Integer type, String payApiType) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("orderNo", orderNO);
        jsonObject.put("type", type);
        jsonObject.put("expireTime", DateTimeUtil.getOneTimeLast());
        jsonObject.put("payApiType", payApiType);
        terControlService.send(RabbitMQData.orderexchange, RabbitMQData.paykey, GatewayProtocol.PAY_SEND, RabbitMQData.orderkey, JSON.toJSONString(jsonObject));
    }

    @Override
    public void refundCallback(String orderNO, String refundNO, String state, String datetime) {
        /**退款异常处理*/
        if (!("SUCCESS").equalsIgnoreCase(state)) {

        }
    }

    @Override
    public void refundCallbackTest(String orderNO, String refundNO, String state, String datetime, Double totalRefundMoney, Double refundMoney, String transactionId) throws Exception {
        if (!redisService.setNx(RedisConstant.REFUND_LOCK + refundNO, RedisConstant.REFUND_LOCK, 60)) {
            log.warn("获取分布式锁失败{}", refundNO);
            return;
        }

        try {
            RefundOrder refundOrder = refundOrderService.fetchRefundOrderWithRetry(refundNO, 3, 1000);
            if (Objects.isNull(refundOrder)){
                log.error("refundorder为空，请排查refundorder插入问题,refundNO={}",refundNO);
                return ;
            }
            /**退款成功*/
            if (("SUCCESS").equalsIgnoreCase(state)) {
                // 退款状态为 失败或者执行中
                if (Objects.nonNull(refundOrder) && !refundOrder.getMsgSuccess()) {
                    PayCallbackData data = new PayCallbackData();
//                    String msgId = String.format("%s_%s", RefundConstant.USER_BALANCE, StringUtil.getRandomString(8));
//                    data.setMsgId(msgId);
//                data.setFeedback("feedback");
                    CallbackDataVo callbackDataVo = new CallbackDataVo();
                    callbackDataVo.setPaymentId(orderNO);  // 第三方支付id - 商户订单号
                    callbackDataVo.setType(2);  // 类型 1 支付 ， 2 退款
                    callbackDataVo.setStatus("SUCCESS");
                    callbackDataVo.setOrderNo(refundNO); // 单号（订单号 退单号）
                    callbackDataVo.setTotalRefundMoney(String.valueOf(totalRefundMoney));
                    callbackDataVo.setRefundMoney(String.valueOf(refundMoney)); // 待确定
                    callbackDataVo.setConfirmTime(datetime);   // 支付时间  退款时间
                    callbackDataVo.setTransactionId(transactionId);  // 平台交易号
                    data.setData(callbackDataVo);
                    // 记录MQ消息内容
//                    refundOrder.setMessageId(msgId);
                    refundOrder.setMessageContent(JSON.toJSONString(data));
                    refundOrder.setRouteKey(RabbitMQData.orderkey);
                    refundOrder.setExchange(RabbitMQData.orderexchange);
                    refundOrder.setMsgSuccess(false);

                    log.info("发送MQ消息{}",JSON.toJSONString(data));
                    // 修改订单退款状态为成功
                    refundOrder.setRefundStatus(RefundConstant.REFUND_SUCCESS);
                    // 跟新退款订单状态
                    refundOrderDao.updateCallBackInfo(refundOrder);
                    // 发送MQ消息
                    mqProducer.sendToRide(RabbitMQData.orderexchange, RabbitMQData.orderkey, JSON.toJSONString(data));
                }
            }
            /**退款异常  退款到银行发现用户的卡作废或者冻结了，导致原路退款银行卡失败，可前往商户平台（pay.weixin.qq.com）-交易中心，手动处理此笔退款 | 退款关闭  商户发起退款失败的情况*/
            if (("CHANGE").equalsIgnoreCase(state) || ("REFUNDCLOSE").equalsIgnoreCase(state)) {
                // 退款状态为执行中
                if (Objects.nonNull(refundOrder) && RefundConstant.REFUND_PENDING.equals(refundOrder.getRefundStatus())) {
                    // 跟新退款订单表状态
                    refundOrder.setRefundStatus(RefundConstant.REFUND_FAIL);
                    // 跟新退款订单状态
                    refundOrderDao.updateCallBackInfo(refundOrder);
                } else {
                    log.error("回调时获取退款订单表为空，排查执行退款时的退款订单表插入动作问题");
                }
            }
        } catch (Exception e) {
            // 记录日志
            log.error("退款回调处理发生异常", e);
            throw new Exception(e);
        } finally {
            redisService.del(RedisConstant.REFUND_LOCK + refundNO);
        }
    }

    /**
     * 获取微信配置信息
     *
     * @param accountId
     * @return
     */
    public WeixinPayConfig getWeixinPayConfig(Integer accountId) {
        /**支付配置信息(1:微信APP支付；2：微信小程序支付)*/
        WeixinPayConfig weixinPayConfig = weixinPayConfigService.getByAccountId(accountId,
                RechargeConstant.RECHARGE_WEIXIN_XCX);
        if (weixinPayConfig == null) {
            throw new BaseException("-2006", "该品牌微信支付未配置");
        }
        return weixinPayConfig;
    }

    /**
     * 获取用户openId
     *
     * @param userId
     * @return
     */
    public UserWxzff getUserWxzff(Integer userId) {
        UserWxzff userWxzff = userWxzffService.getByUserId(userId);
        if (userWxzff == null) {
            return new UserWxzff();
        }
        return userWxzff;
    }

    /**
     * 是否延时分账处理
     *
     * @param delayMoney
     * @param adAccountId
     * @param user
     */
    public void delay(Double delayMoney, Integer adAccountId, User user, String orderNO,Integer rideMoney) {
        UserDelayPay userDelayPay = new UserDelayPay(user.getUserId(), adAccountId, delayMoney, orderNO,rideMoney);
        adaPayService.delay(userDelayPay.getMoney(), user, userDelayPay.getAdAccountId(), userDelayPay.getOrderNO(),rideMoney);
    }


}  